@medalsocial/sdk 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -563,6 +563,165 @@ interface paths {
563
563
  patch?: never;
564
564
  trace?: never;
565
565
  };
566
+ "/api/v1/portal/login/start": {
567
+ parameters: {
568
+ query?: never;
569
+ header?: never;
570
+ path?: never;
571
+ cookie?: never;
572
+ };
573
+ get?: never;
574
+ put?: never;
575
+ /**
576
+ * E-mail a one-time login code
577
+ * @description Always answers 202 `{ status: "sent" }`, whether or not the address belongs to a contact — enumeration-safe by design. Rate-limited per address and per caller (`429 RATE_LIMITED`). Not idempotency-keyed. Errors: `400 VALIDATION_ERROR`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.
578
+ */
579
+ post: operations["startPortalLogin"];
580
+ delete?: never;
581
+ options?: never;
582
+ head?: never;
583
+ patch?: never;
584
+ trace?: never;
585
+ };
586
+ "/api/v1/portal/login/verify": {
587
+ parameters: {
588
+ query?: never;
589
+ header?: never;
590
+ path?: never;
591
+ cookie?: never;
592
+ };
593
+ get?: never;
594
+ put?: never;
595
+ /**
596
+ * Exchange the e-mailed code for a session
597
+ * @description A wrong, burned or expired code all answer `401 PORTAL_CODE_INVALID` — the three are not distinguished, so the response is not an oracle for which codes exist. The returned `session_token` is a bearer credential for ONE contact: keep it in an HttpOnly cookie on the site's server and never hand it to the browser. Not idempotency-keyed. Errors: `400 VALIDATION_ERROR`, `401 PORTAL_CODE_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.
598
+ */
599
+ post: operations["verifyPortalLogin"];
600
+ delete?: never;
601
+ options?: never;
602
+ head?: never;
603
+ patch?: never;
604
+ trace?: never;
605
+ };
606
+ "/api/v1/portal/logout": {
607
+ parameters: {
608
+ query?: never;
609
+ header: {
610
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
611
+ "X-Portal-Session": components["parameters"]["PortalSession"];
612
+ };
613
+ path?: never;
614
+ cookie?: never;
615
+ };
616
+ get?: never;
617
+ put?: never;
618
+ /**
619
+ * Revoke the session
620
+ * @description Revoking twice reaches the same state — the second call answers `401 PORTAL_SESSION_INVALID`. Not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED` (header missing), `401 PORTAL_SESSION_INVALID` (unknown, expired or revoked), `403 FORBIDDEN`, `429 RATE_LIMITED`.
621
+ */
622
+ post: operations["logoutPortal"];
623
+ delete?: never;
624
+ options?: never;
625
+ head?: never;
626
+ patch?: never;
627
+ trace?: never;
628
+ };
629
+ "/api/v1/portal/me": {
630
+ parameters: {
631
+ query?: never;
632
+ header: {
633
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
634
+ "X-Portal-Session": components["parameters"]["PortalSession"];
635
+ };
636
+ path?: never;
637
+ cookie?: never;
638
+ };
639
+ /**
640
+ * The signed-in contact's profile
641
+ * @description Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `read:portal`), `429 RATE_LIMITED`.
642
+ */
643
+ get: operations["getPortalProfile"];
644
+ put?: never;
645
+ post?: never;
646
+ delete?: never;
647
+ options?: never;
648
+ head?: never;
649
+ /**
650
+ * Update the signed-in contact's profile
651
+ * @description Only the supplied fields change. `phone: null` clears the number, `family` replaces the whole list, and `marketing_consent` records a `marketing_email` consent decision with source `portal`. Answers the profile as it is after the change. Errors: `400 VALIDATION_ERROR`, `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.
652
+ */
653
+ patch: operations["updatePortalProfile"];
654
+ trace?: never;
655
+ };
656
+ "/api/v1/portal/me/bookings": {
657
+ parameters: {
658
+ query?: never;
659
+ header: {
660
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
661
+ "X-Portal-Session": components["parameters"]["PortalSession"];
662
+ };
663
+ path?: never;
664
+ cookie?: never;
665
+ };
666
+ /**
667
+ * The signed-in contact's bookings
668
+ * @description Split into `upcoming` and `past`. An upcoming booking still inside the workspace's policy windows carries `manage_token` and `can_manage: true`; the token opens the site's manage page. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.
669
+ */
670
+ get: operations["listPortalBookings"];
671
+ put?: never;
672
+ post?: never;
673
+ delete?: never;
674
+ options?: never;
675
+ head?: never;
676
+ patch?: never;
677
+ trace?: never;
678
+ };
679
+ "/api/v1/portal/me/export": {
680
+ parameters: {
681
+ query?: never;
682
+ header: {
683
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
684
+ "X-Portal-Session": components["parameters"]["PortalSession"];
685
+ };
686
+ path?: never;
687
+ cookie?: never;
688
+ };
689
+ get?: never;
690
+ put?: never;
691
+ /**
692
+ * Export everything held about the signed-in contact
693
+ * @description A synchronous GDPR Art. 15 export of the contact's profile, family, consents and bookings, as one JSON document. Read-only, so not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.
694
+ */
695
+ post: operations["exportPortalData"];
696
+ delete?: never;
697
+ options?: never;
698
+ head?: never;
699
+ patch?: never;
700
+ trace?: never;
701
+ };
702
+ "/api/v1/portal/me/delete": {
703
+ parameters: {
704
+ query?: never;
705
+ header: {
706
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
707
+ "X-Portal-Session": components["parameters"]["PortalSession"];
708
+ };
709
+ path?: never;
710
+ cookie?: never;
711
+ };
712
+ get?: never;
713
+ put?: never;
714
+ /**
715
+ * Erase the signed-in contact
716
+ * @description GDPR Art. 17 erasure. The session is revoked as part of the deletion, so a retry answers `401 PORTAL_SESSION_INVALID` rather than deleting anything else. Not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.
717
+ */
718
+ post: operations["deletePortalAccount"];
719
+ delete?: never;
720
+ options?: never;
721
+ head?: never;
722
+ patch?: never;
723
+ trace?: never;
724
+ };
566
725
  "/api/v1/gdpr/export": {
567
726
  parameters: {
568
727
  query?: never;
@@ -1965,6 +2124,11 @@ interface components {
1965
2124
  ApiResponse_BookingActionResult: components["schemas"]["Envelope_BookingActionResult"];
1966
2125
  ApiResponse_BookingRescheduleResult: components["schemas"]["Envelope_BookingRescheduleResult"];
1967
2126
  ApiResponse_ManageSummary: components["schemas"]["Envelope_ManageSummary"];
2127
+ ApiResponse_PortalLoginStartResult: components["schemas"]["Envelope_PortalLoginStartResult"];
2128
+ ApiResponse_PortalSession: components["schemas"]["Envelope_PortalSession"];
2129
+ ApiResponse_PortalProfile: components["schemas"]["Envelope_PortalProfile"];
2130
+ ApiResponse_PortalBookings: components["schemas"]["Envelope_PortalBookings"];
2131
+ ApiResponse_PortalExport: components["schemas"]["Envelope_PortalExport"];
1968
2132
  ApiResponse_GdprExportRequest: components["schemas"]["Envelope_GdprExportRequest"];
1969
2133
  ApiResponse_GdprExportArray: components["schemas"]["Envelope_GdprExportArray"];
1970
2134
  ApiResponse_GdprExport: components["schemas"]["Envelope_GdprExport"];
@@ -2113,6 +2277,119 @@ interface components {
2113
2277
  Envelope_ManageSummary: {
2114
2278
  data: components["schemas"]["ManageSummary"];
2115
2279
  };
2280
+ PortalLoginStartInput: {
2281
+ /**
2282
+ * Format: email
2283
+ * @description The address the code is sent to.
2284
+ */
2285
+ email: string;
2286
+ /** @description Locale for the e-mail (e.g. `nb`, `en`); the workspace default when omitted. */
2287
+ locale?: string;
2288
+ };
2289
+ /** @description Always `sent`, whether or not the address is a known contact — the route is enumeration-safe by design. */
2290
+ PortalLoginStartResult: {
2291
+ /** @constant */
2292
+ status: "sent";
2293
+ };
2294
+ PortalVerifyInput: {
2295
+ /** Format: email */
2296
+ email: string;
2297
+ /** @description The one-time code from the e-mail. */
2298
+ code: string;
2299
+ };
2300
+ PortalContactSummary: {
2301
+ contact_id: string;
2302
+ first_name: string | null;
2303
+ };
2304
+ /** @description A portal session. `session_token` is a bearer credential for ONE contact — keep it in an HttpOnly cookie on the site's server and never hand it to the browser. */
2305
+ PortalSession: {
2306
+ session_token: string;
2307
+ /** @description Unix timestamp in milliseconds. */
2308
+ expires_at: number;
2309
+ contact: components["schemas"]["PortalContactSummary"];
2310
+ };
2311
+ PortalFamilyMember: {
2312
+ name: string;
2313
+ birth_year: number;
2314
+ };
2315
+ PortalProfile: {
2316
+ contact_id: string;
2317
+ email: string;
2318
+ first_name: string | null;
2319
+ last_name: string | null;
2320
+ phone: string | null;
2321
+ family: components["schemas"]["PortalFamilyMember"][];
2322
+ marketing_consent: boolean;
2323
+ /** @description Unix timestamp in milliseconds. */
2324
+ created_at: number;
2325
+ };
2326
+ /** @description Only the supplied fields change. */
2327
+ PortalProfilePatch: {
2328
+ first_name?: string;
2329
+ last_name?: string;
2330
+ /** @description `null` clears the number. */
2331
+ phone?: string | null;
2332
+ /** @description Replaces the whole list. */
2333
+ family?: components["schemas"]["PortalFamilyMember"][];
2334
+ /** @description Records a `marketing_email` consent change with source `portal`. */
2335
+ marketing_consent?: boolean;
2336
+ };
2337
+ PortalBooking: {
2338
+ booking_id: string;
2339
+ status: components["schemas"]["BookingStatus"];
2340
+ /** @description Unix timestamp in milliseconds. */
2341
+ start_ts: number;
2342
+ /** @description Unix timestamp in milliseconds. */
2343
+ end_ts: number;
2344
+ service_id: string | null;
2345
+ service_name: string | null;
2346
+ resource_id: string | null;
2347
+ resource_name: string | null;
2348
+ booked_for_name: string | null;
2349
+ /** @description Integer øre, or `null` when the service has no price. */
2350
+ amount_ore: number | null;
2351
+ notes: string | null;
2352
+ /** @description Present only while the booking is upcoming and manageable; opens the site's manage page. */
2353
+ manage_token: string | null;
2354
+ can_manage: boolean;
2355
+ };
2356
+ PortalBookings: {
2357
+ upcoming: components["schemas"]["PortalBooking"][];
2358
+ past: components["schemas"]["PortalBooking"][];
2359
+ };
2360
+ PortalConsentRecord: {
2361
+ consent_type: string;
2362
+ granted: boolean;
2363
+ /** @description Unix timestamp in milliseconds, or `null`. */
2364
+ granted_at: number | null;
2365
+ /** @description Unix timestamp in milliseconds, or `null`. */
2366
+ revoked_at: number | null;
2367
+ source: string;
2368
+ };
2369
+ /** @description Everything the workspace holds about the signed-in contact (GDPR Art. 15). */
2370
+ PortalExport: {
2371
+ /** @description Unix timestamp in milliseconds. */
2372
+ exported_at: number;
2373
+ contact: components["schemas"]["PortalProfile"];
2374
+ family: components["schemas"]["PortalFamilyMember"][];
2375
+ consents: components["schemas"]["PortalConsentRecord"][];
2376
+ bookings: components["schemas"]["PortalBooking"][];
2377
+ };
2378
+ Envelope_PortalLoginStartResult: {
2379
+ data: components["schemas"]["PortalLoginStartResult"];
2380
+ };
2381
+ Envelope_PortalSession: {
2382
+ data: components["schemas"]["PortalSession"];
2383
+ };
2384
+ Envelope_PortalProfile: {
2385
+ data: components["schemas"]["PortalProfile"];
2386
+ };
2387
+ Envelope_PortalBookings: {
2388
+ data: components["schemas"]["PortalBookings"];
2389
+ };
2390
+ Envelope_PortalExport: {
2391
+ data: components["schemas"]["PortalExport"];
2392
+ };
2116
2393
  /** @description Provide exactly one of `url`, `orgnr`, or `name`. */
2117
2394
  ScanCreateInput: {
2118
2395
  url?: string;
@@ -2294,6 +2571,8 @@ interface components {
2294
2571
  Slug: string;
2295
2572
  /** @description The show-once manage token handed out when the booking was created. Possession of it authorizes the customer's own cancel or reschedule. */
2296
2573
  ManageToken: string;
2574
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
2575
+ PortalSession: string;
2297
2576
  Cursor: string;
2298
2577
  Limit: number;
2299
2578
  };
@@ -3314,6 +3593,200 @@ interface operations {
3314
3593
  default: components["responses"]["ApiError"];
3315
3594
  };
3316
3595
  };
3596
+ startPortalLogin: {
3597
+ parameters: {
3598
+ query?: never;
3599
+ header?: never;
3600
+ path?: never;
3601
+ cookie?: never;
3602
+ };
3603
+ requestBody: {
3604
+ content: {
3605
+ "application/json": components["schemas"]["PortalLoginStartInput"];
3606
+ };
3607
+ };
3608
+ responses: {
3609
+ /** @description Code queued (or silently not, for an unknown address). */
3610
+ 202: {
3611
+ headers: {
3612
+ [name: string]: unknown;
3613
+ };
3614
+ content: {
3615
+ "application/json": components["schemas"]["ApiResponse_PortalLoginStartResult"];
3616
+ };
3617
+ };
3618
+ default: components["responses"]["ApiError"];
3619
+ };
3620
+ };
3621
+ verifyPortalLogin: {
3622
+ parameters: {
3623
+ query?: never;
3624
+ header?: never;
3625
+ path?: never;
3626
+ cookie?: never;
3627
+ };
3628
+ requestBody: {
3629
+ content: {
3630
+ "application/json": components["schemas"]["PortalVerifyInput"];
3631
+ };
3632
+ };
3633
+ responses: {
3634
+ /** @description The new session. */
3635
+ 200: {
3636
+ headers: {
3637
+ [name: string]: unknown;
3638
+ };
3639
+ content: {
3640
+ "application/json": components["schemas"]["ApiResponse_PortalSession"];
3641
+ };
3642
+ };
3643
+ default: components["responses"]["ApiError"];
3644
+ };
3645
+ };
3646
+ logoutPortal: {
3647
+ parameters: {
3648
+ query?: never;
3649
+ header: {
3650
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
3651
+ "X-Portal-Session": components["parameters"]["PortalSession"];
3652
+ };
3653
+ path?: never;
3654
+ cookie?: never;
3655
+ };
3656
+ requestBody?: never;
3657
+ responses: {
3658
+ /** @description Session revoked. */
3659
+ 204: {
3660
+ headers: {
3661
+ [name: string]: unknown;
3662
+ };
3663
+ content?: never;
3664
+ };
3665
+ default: components["responses"]["ApiError"];
3666
+ };
3667
+ };
3668
+ getPortalProfile: {
3669
+ parameters: {
3670
+ query?: never;
3671
+ header: {
3672
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
3673
+ "X-Portal-Session": components["parameters"]["PortalSession"];
3674
+ };
3675
+ path?: never;
3676
+ cookie?: never;
3677
+ };
3678
+ requestBody?: never;
3679
+ responses: {
3680
+ /** @description Profile. */
3681
+ 200: {
3682
+ headers: {
3683
+ [name: string]: unknown;
3684
+ };
3685
+ content: {
3686
+ "application/json": components["schemas"]["ApiResponse_PortalProfile"];
3687
+ };
3688
+ };
3689
+ default: components["responses"]["ApiError"];
3690
+ };
3691
+ };
3692
+ updatePortalProfile: {
3693
+ parameters: {
3694
+ query?: never;
3695
+ header: {
3696
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
3697
+ "X-Portal-Session": components["parameters"]["PortalSession"];
3698
+ };
3699
+ path?: never;
3700
+ cookie?: never;
3701
+ };
3702
+ requestBody: {
3703
+ content: {
3704
+ "application/json": components["schemas"]["PortalProfilePatch"];
3705
+ };
3706
+ };
3707
+ responses: {
3708
+ /** @description Updated profile. */
3709
+ 200: {
3710
+ headers: {
3711
+ [name: string]: unknown;
3712
+ };
3713
+ content: {
3714
+ "application/json": components["schemas"]["ApiResponse_PortalProfile"];
3715
+ };
3716
+ };
3717
+ default: components["responses"]["ApiError"];
3718
+ };
3719
+ };
3720
+ listPortalBookings: {
3721
+ parameters: {
3722
+ query?: never;
3723
+ header: {
3724
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
3725
+ "X-Portal-Session": components["parameters"]["PortalSession"];
3726
+ };
3727
+ path?: never;
3728
+ cookie?: never;
3729
+ };
3730
+ requestBody?: never;
3731
+ responses: {
3732
+ /** @description Bookings. */
3733
+ 200: {
3734
+ headers: {
3735
+ [name: string]: unknown;
3736
+ };
3737
+ content: {
3738
+ "application/json": components["schemas"]["ApiResponse_PortalBookings"];
3739
+ };
3740
+ };
3741
+ default: components["responses"]["ApiError"];
3742
+ };
3743
+ };
3744
+ exportPortalData: {
3745
+ parameters: {
3746
+ query?: never;
3747
+ header: {
3748
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
3749
+ "X-Portal-Session": components["parameters"]["PortalSession"];
3750
+ };
3751
+ path?: never;
3752
+ cookie?: never;
3753
+ };
3754
+ requestBody?: never;
3755
+ responses: {
3756
+ /** @description The export. */
3757
+ 200: {
3758
+ headers: {
3759
+ [name: string]: unknown;
3760
+ };
3761
+ content: {
3762
+ "application/json": components["schemas"]["ApiResponse_PortalExport"];
3763
+ };
3764
+ };
3765
+ default: components["responses"]["ApiError"];
3766
+ };
3767
+ };
3768
+ deletePortalAccount: {
3769
+ parameters: {
3770
+ query?: never;
3771
+ header: {
3772
+ /** @description The `session_token` returned by `verifyPortalLogin`. A bearer credential for ONE contact — the site's server keeps it in an HttpOnly cookie and forwards it here. Missing answers `401 PORTAL_SESSION_REQUIRED`; unknown, expired or revoked answers `401 PORTAL_SESSION_INVALID`. */
3773
+ "X-Portal-Session": components["parameters"]["PortalSession"];
3774
+ };
3775
+ path?: never;
3776
+ cookie?: never;
3777
+ };
3778
+ requestBody?: never;
3779
+ responses: {
3780
+ /** @description Contact erased and session revoked. */
3781
+ 204: {
3782
+ headers: {
3783
+ [name: string]: unknown;
3784
+ };
3785
+ content?: never;
3786
+ };
3787
+ default: components["responses"]["ApiError"];
3788
+ };
3789
+ };
3317
3790
  requestGdprExport: {
3318
3791
  parameters: {
3319
3792
  query?: never;