-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.yaml
1586 lines (1568 loc) · 53.4 KB
/
api.yaml
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.1
info:
title: CalorieCam Partner API
description: |
Selected partners can use this API to integrate with CalorieCam. Partners can refer user to CalorieCam and receive nutritional data, insights, recommendations and more from authenticated user the partner has referred.
## Authentication
Please contact us at hello@caloriecam.ai to request your API credentials. Include the following information in your request:
- Partner name
- Partner logo URL (square image, PNG or JPEG)
- Webhook URL
Once your request has been reviewed and approved, you can start using the CalorieCam Partner API.
## Referring Users
You can only access data from users that you have referred. Here is how the referral process works and how you receive the CalorieCam user ID:
1. Direct the user to this URL: `https://api.caloriecam.ai/v1/referral?j=JWT_TOKEN`. Note that the JWT must contain all fields specified in the `JWTPayload` model.
2. The user is redirected to the App Store or Google Play Store.
3. The user downloads CalorieCam and sees the correct attribution information on their welcome screen.
4. The user signs up for CalorieCam.
5. A webhook notification is sent containing `UserDetails` including the CalorieCam user ID
You now have the user's CalorieCam UID and can use this UID to make requests.
## Webhooks
To receive updates on user data (e.g., subscription status), you need to provide a webhook URL.
We will send an event to this webhook URL every time a `User` value changes. You must respond with a status 200. CalorieCam retries a single webhook with increasing backoff off between 10 and 600 for 24h.
Please see the `WebhookEvents` model for data structure.
## Subscriptions
The `UserDetails` object contains a `paymentUrl`. This URL redirects the user to a subscription page where they can select and purchase their preferred subscription. Any changes to a subscription (e.g., initial purchase, cancellation, etc.) will trigger an event that you receive on your webhook. Note that users have a choice to purchase a subscription in-app or via the `paymentUrl`. Users who purchase a subscription via the `paymentUrl` will receive a minimum 10% discount on all subscription options.
*When to prompt users to subscribe*
The `UserDetails` object contains a `createdAt` date (when the user signed up) and `freeTrialDays` (the number of free trial days starting from the `createdAt` date). We recommend prompting the user 1-2 days before their free trial expires.
Note that the default number of `freeTrialDays` for partner referred users is 7.
version: 1.0.0
servers:
- url: https://api.caloriecam.ai/v1
description: Main API server
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
JwtPayload:
type: object
properties:
user:
type: object
properties:
id:
type: string
example: UID
description: The unique user id for the user the partner platform.
name:
type: string
example: FirstName LastName
description: The full name of the user.
pt:
type: object
properties:
name:
type: string
example: FirstName LastName
description: The full name of the personal trainer.
id:
type: string
example: UID
description: The unique ID for the personal trainer.
pictureUrl:
type: string
example: PROFILE_PICTURE_URL
description: The URL to the personal trainer's profile picture.
gym:
type: object
properties:
name:
type: string
example: Gym Name
description: The name of the gym.
id:
type: string
example: UID
description: The unique ID for the gym.
pictureUrl:
type: string
description: The URL to the gym's profile picture.
UserDetails:
type: object
properties:
uid:
type: string
description: The unique CalorieCam identifier for the user.
example: 06644ab4-c3c8-4aa5-9768-c624995eb75b
createdAt:
type: string
format: date-time
description: The date and time when the user was created.
photoUrl:
type: string
nullable: true
description: The URL to the user's profile picture.
example: https://firebasestorage.googleapis.com/v0/b/calorie-cam.appspot.com/o/r8BEuxI83XZEjhmwvOk0DSWO8su2%2Flogs%2F06644ab4-c3c8-4aa8-9868-c624995eb7ab.m4a?alt=media&token=a8527846-29d4-43f3-a18b-cd97f82cb111
freeTrialDays:
type: integer
description: The number of free trial days available to the user.
example: 7
name:
type: string
nullable: true
description: The full name of the user. This can be null for some iOS users.
example: John Doe
subscription:
type: object
nullable: true
properties:
priceUsd:
type: number
example: 23.60
description: The subscription price in USD.
price:
type: number
description: The subscription price as a number.
example: 26.60984
currency:
type: string
description: ISO 4217 currency code.
example: AUD
expiresAt:
type: string
format: date-time
description: The expiration date of the subscription.
isActive:
type: boolean
description: Indicates if the subscription is active.
example: true
store:
type: string
enum: [stripe, app_store, play_store]
example: app_store
status:
type: string
description: Describing the status of the subscription.
enum:
[
initialPurchase,
renewal,
cancellation,
uncancellation,
subscriptionPaused,
expiration,
billingIssue,
]
example: initialPurchase
goals:
type: object
description: The daily calorie and macros goals for the user.
properties:
nutrition:
type: object
properties:
macros:
type: object
properties:
carbs:
type: number
description: The amount of carbohydrates in grams.
example: 10
protein:
type: number
description: The amount of protein in grams.
example: 5.5
fat:
type: number
description: The amount of fat in grams.
example: 8.9
calories:
type: number
description: The total number of calories in kcal.
example: 89
paymentUrl:
type: string
description: The url for the user to purchase a subscription
example: https://caloriecam.ai/subscribe?u=123
Meal:
type: object
properties:
createdAt:
type: string
format: date-time
description: The date and time when the meal was created.
id:
type: string
description: The unique identifier for the meal.
example: 1231hf23-12fda23-432asdf43-2345ad1
mealType:
type: string
description: The type of meal.
enum: [breakfast, lunch, dinner, snack]
example: breakfast
context:
type: string
nullable: true
description: User input to give context about the image. Either describes what it is or how much user had. For meals where media.type == audio, this will return the audio transcript.
example: Only had half of it
media:
type: object
nullable: true
properties:
type:
type: string
description: The type of media.
enum: [text, audio, image]
example: image
url:
type: string
description: URL to the image or audio file.
example: https://picsum.photos/200
items:
type: array
description: List of items consumed as part of the meal.
items:
$ref: "#/components/schemas/MealItem"
totals:
nullable: true
type: object
properties:
calories:
type: number
description: The total number of calories for the meal in kcal.
example: 500
macros:
type: object
properties:
carbs:
type: number
description: The total amount of carbohydrates in grams.
example: 40
fat:
type: number
description: The total amount of fat in grams.
example: 29.5
protein:
type: number
description: The total amount of protein in grams.
example: 12
MealItem:
type: object
properties:
name:
type: string
description: The name of the meal item.
example: Banana - medium
calories:
type: number
description: The number of calories in the meal item in kcal.
example: 250
macros:
type: object
properties:
carbs:
type: number
description: The amount of carbohydrates in grams.
example: 12.5
fat:
type: number
description: The amount of fat in grams.
example: 6
protein:
type: number
description: The amount of protein in grams.
example: 2.4
quantity:
type: number
description: The quantity of the meal item.
example: 1
unit:
type: string
description: The unit of measurement for the quantity.
example: serving
NutritionDay:
type: object
properties:
date:
type: string
format: date
description: The date for the log.
calories:
type: number
description: The total number of calories consumed on this date in kcal.
example: 2003
macros:
type: object
properties:
carbs:
type: number
description: The total amount of carbohydrates consumed on this date in grams.
example: 392
fat:
type: number
description: The total amount of fat consumed on this date in grams.
example: 123.2
protein:
type: number
description: The total amount of protein consumed on this date in grams.
example: 164.6
meals:
type: array
description: List of meals consumed on this date.
items:
$ref: "#/components/schemas/Meal"
WeightLog:
type: object
properties:
weight:
type: object
properties:
value:
type: number
description: The weight value.
example: 83
unit:
type: string
description: The unit of the weight. Will always be kg.
example: kg
enum: [kg]
createdAt:
type: string
format: date-time
description: The date and time when the weight was logged.
Insight:
type: object
properties:
rating:
type: string
description: The rating of the insight.
example: negative
title:
type: string
description: The title of the insight.
example: Inconsistent Meal Logging
content:
type: string
description: The content of the insight.
example: There are several days where meals are not logged or inconsistently logged. To better track your progress, please make an effort to log all meals and snacks every day.
logs:
type: array
items:
type: object
properties:
id:
type: string
description: The ID of the log.
example: 88c5351b-087a-4688-94b8-500adfa0a991
rating:
type: string
description: The rating of the log.
example: negative
createdAt:
type: string
format: date-time
description: The creation date of the log.
example: 2024-05-19T12:24:20.000Z
context:
type: string
description: The context of the log.
example: null
mealType:
type: string
description: The type of meal.
example: dinner
media:
type: object
properties:
type:
type: string
description: The type of media.
example: image
url:
type: string
description: The URL of the media.
example: https://example.com/media.jpg
items:
type: array
items:
type: object
properties:
unit:
type: string
description: The unit of the item.
example: serving
macros:
type: object
properties:
carbs:
type: number
description: The amount of carbs.
example: 40
protein:
type: number
description: The amount of protein.
example: 35
fat:
type: number
description: The amount of fat.
example: 50
quantity:
type: number
description: The quantity of the item.
example: 1
name:
type: string
description: The name of the item.
example: cheeseburger with bacon
calories:
type: number
description: The calories of the item.
example: 750
type:
type: string
description: The type of the item.
example: food
totals:
type: object
properties:
calories:
type: number
description: The total calories.
example: 1350
macros:
type: object
properties:
carbs:
type: number
description: The total carbs.
example: 105
fat:
type: number
description: The total fat.
example: 80
protein:
type: number
description: The total protein.
example: 40
ErrorResponse:
type: object
properties:
status:
type: string
example: error
description: The status of the error response.
message:
type: string
description: A descriptive error message.
code:
type: integer
description: The HTTP status code.
examples:
BadRequest:
value:
status: error
message: Bad Request
code: 400
Unauthorized:
value:
status: error
message: Unauthorized
code: 401
NotFound:
value:
status: error
message: Not Found
code: 404
InternalServerError:
value:
status: error
message: Internal Server Error
code: 500
NutritionSuccessResponse:
type: object
properties:
status:
type: string
example: success
description: The status of the success response.
code:
type: integer
description: The HTTP status code.
data:
type: array
description: The data returned in the response.
items:
$ref: "#/components/schemas/NutritionDay"
WeightSuccessResponse:
type: object
properties:
status:
type: string
example: success
description: The status of the success response.
code:
type: integer
description: The HTTP status code.
data:
type: array
description: The data returned in the response.
items:
$ref: "#/components/schemas/WeightLog"
Workout:
type: object
properties:
calories:
type: number
nullable: true
description: Calories burned
createdAt:
type: number
format: int64
description: Unix timestamp in seconds
distance:
type: number
nullable: true
description: Distance covered
duration:
type: number
nullable: true
description: Duration of the workout
end:
type: number
nullable: true
format: int64
description: Unix timestamp in seconds
id:
type: string
description: Unique identifier for the workout
name:
type: string
nullable: true
description: Name of the workout
reps:
type: number
nullable: true
description: Number of repetitions
sets:
type: number
nullable: true
description: Number of sets
source:
type: string
description: Source of the workout data
start:
type: number
nullable: true
format: int64
description: Unix timestamp in seconds
weight:
type: number
nullable: true
description: Weight used during the workout
WebhookEvents:
type: object
properties:
event:
type: string
enum:
- userCreated
- userUpdated
- userDeleted
example: userCreated
createdAt:
type: string
format: date-time
example: "2024-06-24T04:35:07.857Z"
data:
type: object
properties:
uid:
type: string
example: "06644ab4-c3c8-4aa5-9768-c624995eb75b"
createdAt:
type: string
format: date-time
example: "2024-06-24T04:35:07.857Z"
photoUrl:
type: string
format: uri
example: "https://firebasestorage.googleapis.com/v0/b/calorie-cam.appspot.com/o/r8BEuxI83XZEjhmwvOk0DSWO8su2%2Flogs%2F06644ab4-c3c8-4aa8-9868-c624995eb7ab.m4a?alt=media&token=a8527846-29d4-43f3-a18b-cd97f82cb111"
freeTrialDays:
type: integer
example: 7
name:
type: string
example: "John Doe"
subscription:
type: object
properties:
priceUsd:
type: number
example: 23.6
price:
type: number
example: 26.60984
currency:
type: string
example: "AUD"
expiresAt:
type: string
format: date-time
example: "2024-06-24T04:35:07.857Z"
isActive:
type: boolean
example: true
store:
type: string
example: "app_store"
status:
type: string
example: "initialPurchase"
goals:
type: object
properties:
nutrition:
type: object
properties:
macros:
type: object
properties:
carbs:
type: number
example: 10
protein:
type: number
example: 5.5
fat:
type: number
example: 8.9
calories:
type: number
example: 89
paymentUrl:
type: string
format: uri
example: "https://caloriecam.ai/subscribe?u=123"
security:
- BearerAuth: []
paths:
/referral:
post:
summary: Refer a user
description: >
Point a user to this url `https://api.caloriecam.ai/v1/referral?j=JWT_TOKEN` where the `j` query parameter is a JWT token containing the `JwtPayload`. This URL will redirect users to the App/Play Store and will result in a correct attribution. Correctly attributed users' welcome screen in CalorieCam will show all relevant information from the referring partner (e.g. personal trainer, gym, etc.)
tags:
- User
parameters:
- name: j
in: query
required: true
description: JWT token
schema:
type: string
responses:
"302":
description: Redirect to the appropriate resource
headers:
Location:
description: URL to redirect to
schema:
type: string
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Bad Request
code: 400
/nutrition/goals:
post:
summary: Update nutrition goals
description: >
Change the nutrition goals for a user. If specific nutrition goals (calories, carbs, fat, protein) are not provided in the request, the existing values are retained. The provided values must be valid numbers. Use this endpoint with caution and ensure the macros and calories are calorically correct.
tags:
- Nutrition
security:
- BearerAuth: []
parameters:
- name: Authorization
in: header
required: true
description: Bearer token
schema:
type: string
- name: uid
in: query
required: true
description: CalorieCam user ID
schema:
type: string
requestBody:
description: Object containing the nutrition goals
required: true
content:
application/json:
schema:
type: object
properties:
calories:
type: number
description: Daily calorie goal in kcal. Must be a valid number.
example: 2000
carbs:
type: number
description: Daily carbohydrate goal in grams. Must be a valid number.
example: 250
fat:
type: number
description: Daily fat goal in grams. Must be a valid number.
example: 70
protein:
type: number
description: Daily protein goal in grams. Must be a valid number.
example: 150
responses:
"200":
description: Success
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: "Nutrition goals updated successfully"
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Bad Request
code: 400
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Unauthorized
code: 401
"404":
description: Not Found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Not Found
code: 404
"500":
description: Internal Server Error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Internal server error
code: 500
/user:
get:
summary: User details
description: >
Retrieves user details based on the provided CalorieCam user ID (`uid`).
tags:
- User
security:
- BearerAuth: []
parameters:
- name: Authorization
in: header
required: true
description: Bearer token
schema:
type: string
- name: uid
in: query
required: true
description: User ID
schema:
type: string
responses:
"200":
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/UserDetails"
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Bad Request
code: 400
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Unauthorized
code: 401
"404":
description: Not Found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Not Found
code: 404
"500":
description: Internal Server Error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Internal server error
code: 500
/nutrition:
get:
summary: Nutrition logs
description: >
Retrieve nutrition logs for a specified time period. Logs are grouped into days where each day has an array of meals and each meal has an array of items. Totals (calories and macros) are provided for meals and for the day.
tags:
- Nutrition
security:
- BearerAuth: []
parameters:
- name: Authorization
in: header
required: true
description: Bearer token
schema:
type: string
- name: uid
in: query
required: true
description: User ID
schema:
type: string
- name: from
in: query
required: true
description: Start date in ISO 8601 format
schema:
type: string
format: date
- name: to
in: query
required: true
description: End date in ISO 8601 format
schema:
type: string
format: date
responses:
"200":
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/NutritionSuccessResponse"
"204":
description: No Content
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Bad Request
code: 400
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Unauthorized
code: 401
"404":
description: Not Found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Not Found
code: 404
"500":
description: Internal server error.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Internal server error
code: 500
/weight:
get:
summary: Weight logs
description: >
Retrieve body weight logs for a user based on the CalorieCam user ID (`uid`), start date (`from`), and end date (`to`).
tags:
- Weight
security:
- BearerAuth: []
parameters:
- name: Authorization
in: header
required: true
description: Bearer token
schema:
type: string
- name: uid
in: query
required: true
description: User ID
schema:
type: string
- name: from
in: query
required: true
description: Start date in ISO 8601 format
schema:
type: string
format: date
- name: to
in: query
required: true
description: End date in ISO 8601 format
schema:
type: string
format: date
responses:
"200":
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/WeightSuccessResponse"
"204":
description: No Content
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
status: error
message: Bad Request
code: 400