@medalsocial/sdk 1.6.0 → 1.7.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.
- package/README.md +68 -0
- package/dist/openapi/medal-social.openapi.json +3097 -1489
- package/dist/pilot/index.d.mts +2 -2
- package/dist/pilot/index.d.ts +2 -2
- package/dist/src/index.d.mts +593 -23
- package/dist/src/index.d.ts +593 -23
- package/dist/src/index.js +472 -146
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.mjs +471 -146
- package/dist/src/index.mjs.map +1 -1
- package/dist/src/openapi.generated.d.mts +905 -45
- package/dist/src/openapi.generated.d.ts +905 -45
- package/dist/src/openapi.generated.js.map +1 -1
- package/openapi/medal-social.openapi.yaml +944 -0
- package/package.json +18 -17
- package/skills/client/SKILL.md +2 -2
- package/skills/resources/SKILL.md +104 -3
|
@@ -21,6 +21,11 @@ tags:
|
|
|
21
21
|
description: Manage workspace CRM contacts.
|
|
22
22
|
- name: Deals
|
|
23
23
|
description: Manage sponsorship and brand deals.
|
|
24
|
+
- name: Bookings
|
|
25
|
+
description: >-
|
|
26
|
+
Appointment bookings — the service catalogue, free slots, staff actions
|
|
27
|
+
on a booking, and the customer-facing manage-token routes. Money is
|
|
28
|
+
always integer øre.
|
|
24
29
|
- name: GDPR
|
|
25
30
|
description: Manage exports, consent records, and cookie consent.
|
|
26
31
|
- name: Workspaces
|
|
@@ -543,6 +548,356 @@ paths:
|
|
|
543
548
|
$ref: "#/components/schemas/ApiResponse_DealRemoveResult"
|
|
544
549
|
default:
|
|
545
550
|
$ref: "#/components/responses/ApiError"
|
|
551
|
+
/api/v1/bookings:
|
|
552
|
+
get:
|
|
553
|
+
tags: [Bookings]
|
|
554
|
+
operationId: listBookings
|
|
555
|
+
summary: List bookings
|
|
556
|
+
parameters:
|
|
557
|
+
- $ref: "#/components/parameters/Limit"
|
|
558
|
+
- $ref: "#/components/parameters/Cursor"
|
|
559
|
+
- name: from_ts
|
|
560
|
+
in: query
|
|
561
|
+
description: Only bookings starting at or after this instant.
|
|
562
|
+
schema:
|
|
563
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
564
|
+
- name: to_ts
|
|
565
|
+
in: query
|
|
566
|
+
description: Only bookings starting before this instant.
|
|
567
|
+
schema:
|
|
568
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
569
|
+
- name: status
|
|
570
|
+
in: query
|
|
571
|
+
schema:
|
|
572
|
+
$ref: "#/components/schemas/BookingStatus"
|
|
573
|
+
- name: resource_id
|
|
574
|
+
in: query
|
|
575
|
+
schema:
|
|
576
|
+
type: string
|
|
577
|
+
responses:
|
|
578
|
+
"200":
|
|
579
|
+
description: Bookings page.
|
|
580
|
+
content:
|
|
581
|
+
application/json:
|
|
582
|
+
schema:
|
|
583
|
+
$ref: "#/components/schemas/PaginatedResponse_Booking"
|
|
584
|
+
default:
|
|
585
|
+
$ref: "#/components/responses/ApiError"
|
|
586
|
+
post:
|
|
587
|
+
tags: [Bookings]
|
|
588
|
+
operationId: createBooking
|
|
589
|
+
summary: Create a booking or party
|
|
590
|
+
description: >-
|
|
591
|
+
Books every item or none of them. Each created booking carries a
|
|
592
|
+
`manage_token` returned exactly once — only its hash is stored, and an
|
|
593
|
+
idempotent replay omits it.
|
|
594
|
+
requestBody:
|
|
595
|
+
required: true
|
|
596
|
+
content:
|
|
597
|
+
application/json:
|
|
598
|
+
schema:
|
|
599
|
+
$ref: "#/components/schemas/CreateBookingInput"
|
|
600
|
+
responses:
|
|
601
|
+
"201":
|
|
602
|
+
description: Created bookings, in request order.
|
|
603
|
+
content:
|
|
604
|
+
application/json:
|
|
605
|
+
schema:
|
|
606
|
+
$ref: "#/components/schemas/ApiResponse_BookingCreateResult"
|
|
607
|
+
default:
|
|
608
|
+
$ref: "#/components/responses/ApiError"
|
|
609
|
+
/api/v1/bookings/services:
|
|
610
|
+
get:
|
|
611
|
+
tags: [Bookings]
|
|
612
|
+
operationId: listBookingServices
|
|
613
|
+
summary: List bookable services
|
|
614
|
+
parameters:
|
|
615
|
+
- name: include_inactive
|
|
616
|
+
in: query
|
|
617
|
+
description: >-
|
|
618
|
+
Include services with `active: false`. Defaults to active-only.
|
|
619
|
+
schema:
|
|
620
|
+
type: boolean
|
|
621
|
+
responses:
|
|
622
|
+
"200":
|
|
623
|
+
description: Bookable service catalogue.
|
|
624
|
+
content:
|
|
625
|
+
application/json:
|
|
626
|
+
schema:
|
|
627
|
+
$ref: "#/components/schemas/ApiResponse_BookingServiceArray"
|
|
628
|
+
default:
|
|
629
|
+
$ref: "#/components/responses/ApiError"
|
|
630
|
+
/api/v1/bookings/resources:
|
|
631
|
+
get:
|
|
632
|
+
tags: [Bookings]
|
|
633
|
+
operationId: listBookingResources
|
|
634
|
+
summary: List bookable resources
|
|
635
|
+
responses:
|
|
636
|
+
"200":
|
|
637
|
+
description: Bookable resources — staff, rooms, and equipment.
|
|
638
|
+
content:
|
|
639
|
+
application/json:
|
|
640
|
+
schema:
|
|
641
|
+
$ref: "#/components/schemas/ApiResponse_BookingResourceArray"
|
|
642
|
+
default:
|
|
643
|
+
$ref: "#/components/responses/ApiError"
|
|
644
|
+
/api/v1/bookings/availability:
|
|
645
|
+
get:
|
|
646
|
+
tags: [Bookings]
|
|
647
|
+
operationId: listBookingAvailability
|
|
648
|
+
summary: List free slots for a service
|
|
649
|
+
description: >-
|
|
650
|
+
Slots reflect opening hours, time off, buffers, and existing bookings
|
|
651
|
+
at the moment of the call. They are not held.
|
|
652
|
+
parameters:
|
|
653
|
+
- name: service_id
|
|
654
|
+
in: query
|
|
655
|
+
required: true
|
|
656
|
+
schema:
|
|
657
|
+
type: string
|
|
658
|
+
- name: from_ts
|
|
659
|
+
in: query
|
|
660
|
+
required: true
|
|
661
|
+
description: Start of the window.
|
|
662
|
+
schema:
|
|
663
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
664
|
+
- name: to_ts
|
|
665
|
+
in: query
|
|
666
|
+
required: true
|
|
667
|
+
description: End of the window; must be after `from_ts`.
|
|
668
|
+
schema:
|
|
669
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
670
|
+
- name: resource_id
|
|
671
|
+
in: query
|
|
672
|
+
description: Restrict slots to one resource.
|
|
673
|
+
schema:
|
|
674
|
+
type: string
|
|
675
|
+
responses:
|
|
676
|
+
"200":
|
|
677
|
+
description: Free slots.
|
|
678
|
+
content:
|
|
679
|
+
application/json:
|
|
680
|
+
schema:
|
|
681
|
+
$ref: "#/components/schemas/ApiResponse_BookingSlotArray"
|
|
682
|
+
default:
|
|
683
|
+
$ref: "#/components/responses/ApiError"
|
|
684
|
+
/api/v1/bookings/schedule:
|
|
685
|
+
get:
|
|
686
|
+
tags: [Bookings]
|
|
687
|
+
operationId: listBookingSchedule
|
|
688
|
+
summary: List the dates a service can be booked on
|
|
689
|
+
description: >-
|
|
690
|
+
The other half of `availability`. Availability returns free slots and
|
|
691
|
+
nothing else, so a closed day, an evening past closing and a fully
|
|
692
|
+
booked day all come back as the same empty array. This returns one
|
|
693
|
+
entry per date the workspace keeps opening hours on; a date ABSENT from
|
|
694
|
+
the response is closed. `last_start_ts` is the last start this service
|
|
695
|
+
could occupy on that date (it depends on the service's duration and
|
|
696
|
+
buffers, not just the closing time) and is `null` for a date with
|
|
697
|
+
posted hours that is shut outright, such as a public holiday.
|
|
698
|
+
parameters:
|
|
699
|
+
- name: service_id
|
|
700
|
+
in: query
|
|
701
|
+
required: true
|
|
702
|
+
schema:
|
|
703
|
+
type: string
|
|
704
|
+
- name: from_ts
|
|
705
|
+
in: query
|
|
706
|
+
required: true
|
|
707
|
+
description: Start of the window.
|
|
708
|
+
schema:
|
|
709
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
710
|
+
- name: to_ts
|
|
711
|
+
in: query
|
|
712
|
+
required: true
|
|
713
|
+
description: End of the window; must be after `from_ts`.
|
|
714
|
+
schema:
|
|
715
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
716
|
+
- name: resource_id
|
|
717
|
+
in: query
|
|
718
|
+
description: Restrict to one resource's hours.
|
|
719
|
+
schema:
|
|
720
|
+
type: string
|
|
721
|
+
responses:
|
|
722
|
+
"200":
|
|
723
|
+
description: Open dates.
|
|
724
|
+
content:
|
|
725
|
+
application/json:
|
|
726
|
+
schema:
|
|
727
|
+
$ref: "#/components/schemas/ApiResponse_BookingScheduleDayArray"
|
|
728
|
+
default:
|
|
729
|
+
$ref: "#/components/responses/ApiError"
|
|
730
|
+
/api/v1/bookings/{id}:
|
|
731
|
+
parameters:
|
|
732
|
+
- $ref: "#/components/parameters/Id"
|
|
733
|
+
get:
|
|
734
|
+
tags: [Bookings]
|
|
735
|
+
operationId: getBooking
|
|
736
|
+
summary: Get a booking
|
|
737
|
+
responses:
|
|
738
|
+
"200":
|
|
739
|
+
description: Booking.
|
|
740
|
+
content:
|
|
741
|
+
application/json:
|
|
742
|
+
schema:
|
|
743
|
+
$ref: "#/components/schemas/ApiResponse_Booking"
|
|
744
|
+
default:
|
|
745
|
+
$ref: "#/components/responses/ApiError"
|
|
746
|
+
patch:
|
|
747
|
+
tags: [Bookings]
|
|
748
|
+
operationId: updateBooking
|
|
749
|
+
summary: Annotate a booking
|
|
750
|
+
requestBody:
|
|
751
|
+
required: true
|
|
752
|
+
content:
|
|
753
|
+
application/json:
|
|
754
|
+
schema:
|
|
755
|
+
$ref: "#/components/schemas/UpdateBookingInput"
|
|
756
|
+
responses:
|
|
757
|
+
"200":
|
|
758
|
+
description: The updated booking.
|
|
759
|
+
content:
|
|
760
|
+
application/json:
|
|
761
|
+
schema:
|
|
762
|
+
$ref: "#/components/schemas/ApiResponse_Booking"
|
|
763
|
+
default:
|
|
764
|
+
$ref: "#/components/responses/ApiError"
|
|
765
|
+
/api/v1/bookings/{id}/cancel:
|
|
766
|
+
parameters:
|
|
767
|
+
- $ref: "#/components/parameters/Id"
|
|
768
|
+
post:
|
|
769
|
+
tags: [Bookings]
|
|
770
|
+
operationId: cancelBooking
|
|
771
|
+
summary: Cancel a booking as the business
|
|
772
|
+
description: >-
|
|
773
|
+
Staff semantics — the workspace's cancel window is bypassed and the
|
|
774
|
+
cancellation is attributed to staff.
|
|
775
|
+
requestBody:
|
|
776
|
+
required: true
|
|
777
|
+
content:
|
|
778
|
+
application/json:
|
|
779
|
+
schema:
|
|
780
|
+
$ref: "#/components/schemas/CancelBookingInput"
|
|
781
|
+
responses:
|
|
782
|
+
"200":
|
|
783
|
+
description: Cancel result.
|
|
784
|
+
content:
|
|
785
|
+
application/json:
|
|
786
|
+
schema:
|
|
787
|
+
$ref: "#/components/schemas/ApiResponse_BookingActionResult"
|
|
788
|
+
default:
|
|
789
|
+
$ref: "#/components/responses/ApiError"
|
|
790
|
+
/api/v1/bookings/{id}/reschedule:
|
|
791
|
+
parameters:
|
|
792
|
+
- $ref: "#/components/parameters/Id"
|
|
793
|
+
post:
|
|
794
|
+
tags: [Bookings]
|
|
795
|
+
operationId: rescheduleBooking
|
|
796
|
+
summary: Reschedule a booking as the business
|
|
797
|
+
description: >-
|
|
798
|
+
Staff semantics — the reschedule window is bypassed. The old booking is
|
|
799
|
+
cancelled and a new one inserted, so the response carries a new booking
|
|
800
|
+
id and a freshly minted manage token.
|
|
801
|
+
requestBody:
|
|
802
|
+
required: true
|
|
803
|
+
content:
|
|
804
|
+
application/json:
|
|
805
|
+
schema:
|
|
806
|
+
$ref: "#/components/schemas/RescheduleBookingInput"
|
|
807
|
+
responses:
|
|
808
|
+
"200":
|
|
809
|
+
description: Reschedule result.
|
|
810
|
+
content:
|
|
811
|
+
application/json:
|
|
812
|
+
schema:
|
|
813
|
+
$ref: "#/components/schemas/ApiResponse_BookingRescheduleResult"
|
|
814
|
+
default:
|
|
815
|
+
$ref: "#/components/responses/ApiError"
|
|
816
|
+
/api/v1/bookings/{id}/no-show:
|
|
817
|
+
parameters:
|
|
818
|
+
- $ref: "#/components/parameters/Id"
|
|
819
|
+
post:
|
|
820
|
+
tags: [Bookings]
|
|
821
|
+
operationId: markBookingNoShow
|
|
822
|
+
summary: Mark a booking as a no-show
|
|
823
|
+
responses:
|
|
824
|
+
"200":
|
|
825
|
+
description: No-show result.
|
|
826
|
+
content:
|
|
827
|
+
application/json:
|
|
828
|
+
schema:
|
|
829
|
+
$ref: "#/components/schemas/ApiResponse_BookingActionResult"
|
|
830
|
+
default:
|
|
831
|
+
$ref: "#/components/responses/ApiError"
|
|
832
|
+
/api/v1/bookings/manage/{token}:
|
|
833
|
+
parameters:
|
|
834
|
+
- $ref: "#/components/parameters/ManageToken"
|
|
835
|
+
get:
|
|
836
|
+
tags: [Bookings]
|
|
837
|
+
operationId: getManagedBooking
|
|
838
|
+
summary: Get the customer manage summary for a token
|
|
839
|
+
responses:
|
|
840
|
+
"200":
|
|
841
|
+
description: >-
|
|
842
|
+
Manage summary. An unknown token and a token belonging to another
|
|
843
|
+
workspace both answer 404, so this is not an existence oracle.
|
|
844
|
+
content:
|
|
845
|
+
application/json:
|
|
846
|
+
schema:
|
|
847
|
+
$ref: "#/components/schemas/ApiResponse_ManageSummary"
|
|
848
|
+
default:
|
|
849
|
+
$ref: "#/components/responses/ApiError"
|
|
850
|
+
/api/v1/bookings/manage/{token}/cancel:
|
|
851
|
+
parameters:
|
|
852
|
+
- $ref: "#/components/parameters/ManageToken"
|
|
853
|
+
post:
|
|
854
|
+
tags: [Bookings]
|
|
855
|
+
operationId: cancelManagedBooking
|
|
856
|
+
summary: Cancel on the customer's behalf
|
|
857
|
+
description: >-
|
|
858
|
+
Customer semantics — the workspace's cancel window is ENFORCED and the
|
|
859
|
+
cancellation is attributed to the customer.
|
|
860
|
+
requestBody:
|
|
861
|
+
required: true
|
|
862
|
+
content:
|
|
863
|
+
application/json:
|
|
864
|
+
schema:
|
|
865
|
+
$ref: "#/components/schemas/CancelBookingInput"
|
|
866
|
+
responses:
|
|
867
|
+
"200":
|
|
868
|
+
description: Cancel result.
|
|
869
|
+
content:
|
|
870
|
+
application/json:
|
|
871
|
+
schema:
|
|
872
|
+
$ref: "#/components/schemas/ApiResponse_BookingActionResult"
|
|
873
|
+
default:
|
|
874
|
+
$ref: "#/components/responses/ApiError"
|
|
875
|
+
/api/v1/bookings/manage/{token}/reschedule:
|
|
876
|
+
parameters:
|
|
877
|
+
- $ref: "#/components/parameters/ManageToken"
|
|
878
|
+
post:
|
|
879
|
+
tags: [Bookings]
|
|
880
|
+
operationId: rescheduleManagedBooking
|
|
881
|
+
summary: Reschedule on the customer's behalf
|
|
882
|
+
description: >-
|
|
883
|
+
Customer semantics — the reschedule window is ENFORCED. The response
|
|
884
|
+
carries a new booking id and a new manage token; the old token stops
|
|
885
|
+
working.
|
|
886
|
+
requestBody:
|
|
887
|
+
required: true
|
|
888
|
+
content:
|
|
889
|
+
application/json:
|
|
890
|
+
schema:
|
|
891
|
+
$ref: "#/components/schemas/RescheduleBookingInput"
|
|
892
|
+
responses:
|
|
893
|
+
"200":
|
|
894
|
+
description: Reschedule result.
|
|
895
|
+
content:
|
|
896
|
+
application/json:
|
|
897
|
+
schema:
|
|
898
|
+
$ref: "#/components/schemas/ApiResponse_BookingRescheduleResult"
|
|
899
|
+
default:
|
|
900
|
+
$ref: "#/components/responses/ApiError"
|
|
546
901
|
/api/v1/gdpr/export:
|
|
547
902
|
post:
|
|
548
903
|
tags: [GDPR]
|
|
@@ -1177,6 +1532,15 @@ components:
|
|
|
1177
1532
|
required: true
|
|
1178
1533
|
schema:
|
|
1179
1534
|
type: string
|
|
1535
|
+
ManageToken:
|
|
1536
|
+
name: token
|
|
1537
|
+
in: path
|
|
1538
|
+
required: true
|
|
1539
|
+
description: >-
|
|
1540
|
+
The show-once manage token handed out when the booking was created.
|
|
1541
|
+
Possession of it authorizes the customer's own cancel or reschedule.
|
|
1542
|
+
schema:
|
|
1543
|
+
type: string
|
|
1180
1544
|
Cursor:
|
|
1181
1545
|
name: cursor
|
|
1182
1546
|
in: query
|
|
@@ -2051,6 +2415,496 @@ components:
|
|
|
2051
2415
|
format: date
|
|
2052
2416
|
notes:
|
|
2053
2417
|
type: string
|
|
2418
|
+
BookingTimestampInput:
|
|
2419
|
+
description: >-
|
|
2420
|
+
A timestamp on the way in — Unix milliseconds, or an ISO 8601
|
|
2421
|
+
date-time string. Responses always render timestamps as ISO 8601.
|
|
2422
|
+
type: [integer, string]
|
|
2423
|
+
BookingStatus:
|
|
2424
|
+
type: string
|
|
2425
|
+
enum: [pending, confirmed, completed, cancelled, no_show]
|
|
2426
|
+
BookingCancelledBy:
|
|
2427
|
+
description: >-
|
|
2428
|
+
Who cancelled. `staff` for the id-addressed cancel, `customer` for the
|
|
2429
|
+
manage-token cancel, `system` for an automated one.
|
|
2430
|
+
type: string
|
|
2431
|
+
enum: [customer, staff, system]
|
|
2432
|
+
BookingPaymentStatus:
|
|
2433
|
+
type: string
|
|
2434
|
+
enum: [none, reserved, captured, refunded]
|
|
2435
|
+
BookingCreatedVia:
|
|
2436
|
+
type: string
|
|
2437
|
+
enum: [web, dashboard, walk_in, api]
|
|
2438
|
+
BookingResourceType:
|
|
2439
|
+
type: string
|
|
2440
|
+
enum: [staff, room, equipment]
|
|
2441
|
+
Booking:
|
|
2442
|
+
type: object
|
|
2443
|
+
required:
|
|
2444
|
+
- id
|
|
2445
|
+
- contact_id
|
|
2446
|
+
- service_id
|
|
2447
|
+
- resource_id
|
|
2448
|
+
- start_ts
|
|
2449
|
+
- end_ts
|
|
2450
|
+
- booked_for_name
|
|
2451
|
+
- booked_for_birth_year
|
|
2452
|
+
- party_sequence_id
|
|
2453
|
+
- status
|
|
2454
|
+
- cancelled_by
|
|
2455
|
+
- cancel_reason
|
|
2456
|
+
- rescheduled_from_id
|
|
2457
|
+
- payment_status
|
|
2458
|
+
- amount_ore
|
|
2459
|
+
- notes
|
|
2460
|
+
- internal_notes
|
|
2461
|
+
- created_via
|
|
2462
|
+
- created_at
|
|
2463
|
+
- updated_at
|
|
2464
|
+
properties:
|
|
2465
|
+
id:
|
|
2466
|
+
type: string
|
|
2467
|
+
contact_id:
|
|
2468
|
+
type: [string, "null"]
|
|
2469
|
+
service_id:
|
|
2470
|
+
type: [string, "null"]
|
|
2471
|
+
resource_id:
|
|
2472
|
+
type: [string, "null"]
|
|
2473
|
+
start_ts:
|
|
2474
|
+
type: [string, "null"]
|
|
2475
|
+
format: date-time
|
|
2476
|
+
end_ts:
|
|
2477
|
+
type: [string, "null"]
|
|
2478
|
+
format: date-time
|
|
2479
|
+
booked_for_name:
|
|
2480
|
+
type: [string, "null"]
|
|
2481
|
+
booked_for_birth_year:
|
|
2482
|
+
description: A birth year, not a birthdate — the age bracket is all that is stored.
|
|
2483
|
+
type: [integer, "null"]
|
|
2484
|
+
party_sequence_id:
|
|
2485
|
+
description: Shared by every booking created in the same party request.
|
|
2486
|
+
type: [string, "null"]
|
|
2487
|
+
status:
|
|
2488
|
+
$ref: "#/components/schemas/BookingStatus"
|
|
2489
|
+
cancelled_by:
|
|
2490
|
+
oneOf:
|
|
2491
|
+
- $ref: "#/components/schemas/BookingCancelledBy"
|
|
2492
|
+
- type: "null"
|
|
2493
|
+
cancel_reason:
|
|
2494
|
+
type: [string, "null"]
|
|
2495
|
+
rescheduled_from_id:
|
|
2496
|
+
description: On a booking created by a reschedule, the booking it replaced.
|
|
2497
|
+
type: [string, "null"]
|
|
2498
|
+
payment_status:
|
|
2499
|
+
$ref: "#/components/schemas/BookingPaymentStatus"
|
|
2500
|
+
amount_ore:
|
|
2501
|
+
description: Price in integer øre. Never a float and never kroner.
|
|
2502
|
+
type: [integer, "null"]
|
|
2503
|
+
notes:
|
|
2504
|
+
description: Customer-visible note.
|
|
2505
|
+
type: [string, "null"]
|
|
2506
|
+
internal_notes:
|
|
2507
|
+
description: Staff-only note; never shown to the customer.
|
|
2508
|
+
type: [string, "null"]
|
|
2509
|
+
created_via:
|
|
2510
|
+
oneOf:
|
|
2511
|
+
- $ref: "#/components/schemas/BookingCreatedVia"
|
|
2512
|
+
- type: "null"
|
|
2513
|
+
created_at:
|
|
2514
|
+
type: [string, "null"]
|
|
2515
|
+
format: date-time
|
|
2516
|
+
updated_at:
|
|
2517
|
+
type: [string, "null"]
|
|
2518
|
+
format: date-time
|
|
2519
|
+
BookingService:
|
|
2520
|
+
type: object
|
|
2521
|
+
required:
|
|
2522
|
+
- id
|
|
2523
|
+
- name
|
|
2524
|
+
- description
|
|
2525
|
+
- category
|
|
2526
|
+
- duration_minutes
|
|
2527
|
+
- buffer_before_minutes
|
|
2528
|
+
- buffer_after_minutes
|
|
2529
|
+
- price_ore
|
|
2530
|
+
- weekend_surcharge_pct
|
|
2531
|
+
- resource_requirements
|
|
2532
|
+
- bookable_online
|
|
2533
|
+
- max_per_booking
|
|
2534
|
+
- color
|
|
2535
|
+
- sort_order
|
|
2536
|
+
- active
|
|
2537
|
+
- created_at
|
|
2538
|
+
- updated_at
|
|
2539
|
+
properties:
|
|
2540
|
+
id:
|
|
2541
|
+
type: string
|
|
2542
|
+
name:
|
|
2543
|
+
type: [string, "null"]
|
|
2544
|
+
description:
|
|
2545
|
+
type: [string, "null"]
|
|
2546
|
+
category:
|
|
2547
|
+
type: [string, "null"]
|
|
2548
|
+
duration_minutes:
|
|
2549
|
+
type: [integer, "null"]
|
|
2550
|
+
buffer_before_minutes:
|
|
2551
|
+
type: [integer, "null"]
|
|
2552
|
+
buffer_after_minutes:
|
|
2553
|
+
type: [integer, "null"]
|
|
2554
|
+
price_ore:
|
|
2555
|
+
description: Price in integer øre.
|
|
2556
|
+
type: [integer, "null"]
|
|
2557
|
+
weekend_surcharge_pct:
|
|
2558
|
+
type: [number, "null"]
|
|
2559
|
+
resource_requirements:
|
|
2560
|
+
description: Resource types this service needs, e.g. `["staff"]`.
|
|
2561
|
+
type: array
|
|
2562
|
+
items:
|
|
2563
|
+
type: string
|
|
2564
|
+
bookable_online:
|
|
2565
|
+
type: boolean
|
|
2566
|
+
max_per_booking:
|
|
2567
|
+
type: [integer, "null"]
|
|
2568
|
+
color:
|
|
2569
|
+
type: [string, "null"]
|
|
2570
|
+
sort_order:
|
|
2571
|
+
type: [integer, "null"]
|
|
2572
|
+
active:
|
|
2573
|
+
type: boolean
|
|
2574
|
+
created_at:
|
|
2575
|
+
type: [string, "null"]
|
|
2576
|
+
format: date-time
|
|
2577
|
+
updated_at:
|
|
2578
|
+
type: [string, "null"]
|
|
2579
|
+
format: date-time
|
|
2580
|
+
BookingResource:
|
|
2581
|
+
type: object
|
|
2582
|
+
required:
|
|
2583
|
+
- id
|
|
2584
|
+
- type
|
|
2585
|
+
- name
|
|
2586
|
+
- photo_url
|
|
2587
|
+
- bio
|
|
2588
|
+
- service_ids
|
|
2589
|
+
- capacity
|
|
2590
|
+
- sort_order
|
|
2591
|
+
- active
|
|
2592
|
+
- created_at
|
|
2593
|
+
- updated_at
|
|
2594
|
+
properties:
|
|
2595
|
+
id:
|
|
2596
|
+
type: string
|
|
2597
|
+
type:
|
|
2598
|
+
oneOf:
|
|
2599
|
+
- $ref: "#/components/schemas/BookingResourceType"
|
|
2600
|
+
- type: "null"
|
|
2601
|
+
name:
|
|
2602
|
+
type: [string, "null"]
|
|
2603
|
+
photo_url:
|
|
2604
|
+
type: [string, "null"]
|
|
2605
|
+
format: uri
|
|
2606
|
+
bio:
|
|
2607
|
+
type: [string, "null"]
|
|
2608
|
+
service_ids:
|
|
2609
|
+
description: Services this resource can perform.
|
|
2610
|
+
type: array
|
|
2611
|
+
items:
|
|
2612
|
+
type: string
|
|
2613
|
+
capacity:
|
|
2614
|
+
type: [integer, "null"]
|
|
2615
|
+
sort_order:
|
|
2616
|
+
type: [integer, "null"]
|
|
2617
|
+
active:
|
|
2618
|
+
type: boolean
|
|
2619
|
+
created_at:
|
|
2620
|
+
type: [string, "null"]
|
|
2621
|
+
format: date-time
|
|
2622
|
+
updated_at:
|
|
2623
|
+
type: [string, "null"]
|
|
2624
|
+
format: date-time
|
|
2625
|
+
BookingSlot:
|
|
2626
|
+
type: object
|
|
2627
|
+
required: [start_ts, end_ts, resource_id]
|
|
2628
|
+
properties:
|
|
2629
|
+
start_ts:
|
|
2630
|
+
type: [string, "null"]
|
|
2631
|
+
format: date-time
|
|
2632
|
+
end_ts:
|
|
2633
|
+
type: [string, "null"]
|
|
2634
|
+
format: date-time
|
|
2635
|
+
resource_id:
|
|
2636
|
+
type: [string, "null"]
|
|
2637
|
+
BookingScheduleDay:
|
|
2638
|
+
description: One date a service can be booked on. `date` is the workspace's own calendar date, not a timestamp.
|
|
2639
|
+
type: object
|
|
2640
|
+
required: [date, opens_ts, closes_ts, last_start_ts]
|
|
2641
|
+
properties:
|
|
2642
|
+
date:
|
|
2643
|
+
type: [string, "null"]
|
|
2644
|
+
format: date
|
|
2645
|
+
opens_ts:
|
|
2646
|
+
type: [string, "null"]
|
|
2647
|
+
format: date-time
|
|
2648
|
+
closes_ts:
|
|
2649
|
+
type: [string, "null"]
|
|
2650
|
+
format: date-time
|
|
2651
|
+
last_start_ts:
|
|
2652
|
+
description: Last start this service could occupy on the date; `null` when the date is shut outright.
|
|
2653
|
+
type: [string, "null"]
|
|
2654
|
+
format: date-time
|
|
2655
|
+
BookingContactInput:
|
|
2656
|
+
description: The person the booking is made under. Phone is the CRM dedupe key.
|
|
2657
|
+
type: object
|
|
2658
|
+
required: [phone]
|
|
2659
|
+
properties:
|
|
2660
|
+
phone:
|
|
2661
|
+
type: string
|
|
2662
|
+
maxLength: 40
|
|
2663
|
+
email:
|
|
2664
|
+
type: string
|
|
2665
|
+
maxLength: 320
|
|
2666
|
+
name:
|
|
2667
|
+
type: string
|
|
2668
|
+
maxLength: 200
|
|
2669
|
+
CreateBookingItemInput:
|
|
2670
|
+
description: One line of a party — a single service on a single slot.
|
|
2671
|
+
type: object
|
|
2672
|
+
required: [service_id, start_ts]
|
|
2673
|
+
properties:
|
|
2674
|
+
service_id:
|
|
2675
|
+
type: string
|
|
2676
|
+
resource_id:
|
|
2677
|
+
description: Omit to let the engine pick a free resource.
|
|
2678
|
+
type: string
|
|
2679
|
+
start_ts:
|
|
2680
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
2681
|
+
booked_for_name:
|
|
2682
|
+
type: string
|
|
2683
|
+
maxLength: 200
|
|
2684
|
+
booked_for_birth_year:
|
|
2685
|
+
type: integer
|
|
2686
|
+
minimum: 1900
|
|
2687
|
+
maximum: 2200
|
|
2688
|
+
CreateBookingInput:
|
|
2689
|
+
type: object
|
|
2690
|
+
required: [items, contact]
|
|
2691
|
+
properties:
|
|
2692
|
+
items:
|
|
2693
|
+
description: >-
|
|
2694
|
+
A PARTY — one request books a whole family in one all-or-nothing
|
|
2695
|
+
transaction.
|
|
2696
|
+
type: array
|
|
2697
|
+
minItems: 1
|
|
2698
|
+
maxItems: 50
|
|
2699
|
+
items:
|
|
2700
|
+
$ref: "#/components/schemas/CreateBookingItemInput"
|
|
2701
|
+
contact:
|
|
2702
|
+
$ref: "#/components/schemas/BookingContactInput"
|
|
2703
|
+
notes:
|
|
2704
|
+
type: string
|
|
2705
|
+
maxLength: 5000
|
|
2706
|
+
created_via:
|
|
2707
|
+
description: >-
|
|
2708
|
+
Where the booking came from. Defaults to `api`. A workspace's OWN
|
|
2709
|
+
website should send `web`, so its bookings can be told apart from
|
|
2710
|
+
integrations. `dashboard` and `walk_in` are staff-only and are
|
|
2711
|
+
rejected with 400 — a bearer token proves which workspace is calling,
|
|
2712
|
+
not that a member typed the booking in.
|
|
2713
|
+
type: string
|
|
2714
|
+
enum: [web, api]
|
|
2715
|
+
CreatedBooking:
|
|
2716
|
+
type: object
|
|
2717
|
+
required: [id]
|
|
2718
|
+
properties:
|
|
2719
|
+
id:
|
|
2720
|
+
type: string
|
|
2721
|
+
manage_token:
|
|
2722
|
+
description: >-
|
|
2723
|
+
Show-once secret for the customer's manage link. Only its hash is
|
|
2724
|
+
stored, and an idempotent replay omits this field entirely.
|
|
2725
|
+
type: string
|
|
2726
|
+
BookingCreateResult:
|
|
2727
|
+
type: object
|
|
2728
|
+
required: [bookings, contact_id]
|
|
2729
|
+
properties:
|
|
2730
|
+
bookings:
|
|
2731
|
+
description: One entry per created booking, in request order.
|
|
2732
|
+
type: array
|
|
2733
|
+
items:
|
|
2734
|
+
$ref: "#/components/schemas/CreatedBooking"
|
|
2735
|
+
contact_id:
|
|
2736
|
+
type: string
|
|
2737
|
+
BookingActionResult:
|
|
2738
|
+
type: object
|
|
2739
|
+
required: [success]
|
|
2740
|
+
properties:
|
|
2741
|
+
success:
|
|
2742
|
+
type: boolean
|
|
2743
|
+
const: true
|
|
2744
|
+
BookingRescheduleResult:
|
|
2745
|
+
type: object
|
|
2746
|
+
required: [success, booking_id]
|
|
2747
|
+
properties:
|
|
2748
|
+
success:
|
|
2749
|
+
type: boolean
|
|
2750
|
+
const: true
|
|
2751
|
+
booking_id:
|
|
2752
|
+
description: >-
|
|
2753
|
+
The NEW booking's id — a reschedule cancels the old row and inserts
|
|
2754
|
+
a new one.
|
|
2755
|
+
type: string
|
|
2756
|
+
manage_token:
|
|
2757
|
+
description: >-
|
|
2758
|
+
Freshly minted manage token for the new booking; omitted on an
|
|
2759
|
+
idempotent replay.
|
|
2760
|
+
type: string
|
|
2761
|
+
ManageSummary:
|
|
2762
|
+
description: >-
|
|
2763
|
+
What the holder of a manage token may see and do. `can_cancel` and
|
|
2764
|
+
`can_reschedule` already apply the workspace's policy windows.
|
|
2765
|
+
type: object
|
|
2766
|
+
required:
|
|
2767
|
+
- booking_id
|
|
2768
|
+
- contact_id
|
|
2769
|
+
- status
|
|
2770
|
+
- cancelled_by
|
|
2771
|
+
- cancel_reason
|
|
2772
|
+
- rescheduled_from_id
|
|
2773
|
+
- start_ts
|
|
2774
|
+
- end_ts
|
|
2775
|
+
- service_id
|
|
2776
|
+
- service_name
|
|
2777
|
+
- resource_id
|
|
2778
|
+
- resource_name
|
|
2779
|
+
- booked_for_name
|
|
2780
|
+
- party_sequence_id
|
|
2781
|
+
- amount_ore
|
|
2782
|
+
- payment_status
|
|
2783
|
+
- time_zone
|
|
2784
|
+
- cancel_window_hours
|
|
2785
|
+
- reschedule_window_hours
|
|
2786
|
+
- can_cancel
|
|
2787
|
+
- can_reschedule
|
|
2788
|
+
properties:
|
|
2789
|
+
booking_id:
|
|
2790
|
+
type: string
|
|
2791
|
+
contact_id:
|
|
2792
|
+
type: [string, "null"]
|
|
2793
|
+
status:
|
|
2794
|
+
oneOf:
|
|
2795
|
+
- $ref: "#/components/schemas/BookingStatus"
|
|
2796
|
+
- type: "null"
|
|
2797
|
+
cancelled_by:
|
|
2798
|
+
oneOf:
|
|
2799
|
+
- $ref: "#/components/schemas/BookingCancelledBy"
|
|
2800
|
+
- type: "null"
|
|
2801
|
+
cancel_reason:
|
|
2802
|
+
type: [string, "null"]
|
|
2803
|
+
rescheduled_from_id:
|
|
2804
|
+
type: [string, "null"]
|
|
2805
|
+
start_ts:
|
|
2806
|
+
type: [string, "null"]
|
|
2807
|
+
format: date-time
|
|
2808
|
+
end_ts:
|
|
2809
|
+
type: [string, "null"]
|
|
2810
|
+
format: date-time
|
|
2811
|
+
service_id:
|
|
2812
|
+
type: [string, "null"]
|
|
2813
|
+
service_name:
|
|
2814
|
+
type: [string, "null"]
|
|
2815
|
+
resource_id:
|
|
2816
|
+
type: [string, "null"]
|
|
2817
|
+
resource_name:
|
|
2818
|
+
type: [string, "null"]
|
|
2819
|
+
booked_for_name:
|
|
2820
|
+
type: [string, "null"]
|
|
2821
|
+
party_sequence_id:
|
|
2822
|
+
type: [string, "null"]
|
|
2823
|
+
amount_ore:
|
|
2824
|
+
description: Price in integer øre.
|
|
2825
|
+
type: [integer, "null"]
|
|
2826
|
+
payment_status:
|
|
2827
|
+
oneOf:
|
|
2828
|
+
- $ref: "#/components/schemas/BookingPaymentStatus"
|
|
2829
|
+
- type: "null"
|
|
2830
|
+
time_zone:
|
|
2831
|
+
description: IANA zone the booking's local times should be rendered in.
|
|
2832
|
+
type: [string, "null"]
|
|
2833
|
+
cancel_window_hours:
|
|
2834
|
+
type: [number, "null"]
|
|
2835
|
+
reschedule_window_hours:
|
|
2836
|
+
type: [number, "null"]
|
|
2837
|
+
can_cancel:
|
|
2838
|
+
type: boolean
|
|
2839
|
+
can_reschedule:
|
|
2840
|
+
type: boolean
|
|
2841
|
+
UpdateBookingInput:
|
|
2842
|
+
description: >-
|
|
2843
|
+
At least one of `notes` or `internal_notes` is required — the API
|
|
2844
|
+
rejects a body carrying neither with a 400. `""` is a meaningful value
|
|
2845
|
+
that clears the field, so the constraint is on presence.
|
|
2846
|
+
# Spelled out as two fully-typed branches rather than the terser
|
|
2847
|
+
# `anyOf: [{required: [notes]}, {required: [internal_notes]}]`, because a
|
|
2848
|
+
# branch carrying only `required` generates as `unknown` — and `T |
|
|
2849
|
+
# unknown` collapses to `unknown`, which accepts everything and is worse
|
|
2850
|
+
# than the unconstrained object. Each branch therefore repeats the
|
|
2851
|
+
# properties so openapi-typescript emits a real discriminating union.
|
|
2852
|
+
#
|
|
2853
|
+
# `minProperties: 1` is deliberately absent: `anyOf` on two named
|
|
2854
|
+
# properties already implies it and is strictly stronger (it also rejects
|
|
2855
|
+
# `{ unrelated_key: 1 }`), so keeping both would be two statements of one
|
|
2856
|
+
# invariant to drift apart.
|
|
2857
|
+
anyOf:
|
|
2858
|
+
- type: object
|
|
2859
|
+
required: [notes]
|
|
2860
|
+
properties:
|
|
2861
|
+
notes:
|
|
2862
|
+
description: Customer-visible note.
|
|
2863
|
+
type: string
|
|
2864
|
+
maxLength: 5000
|
|
2865
|
+
internal_notes:
|
|
2866
|
+
description: Staff-only note.
|
|
2867
|
+
type: string
|
|
2868
|
+
maxLength: 5000
|
|
2869
|
+
- type: object
|
|
2870
|
+
required: [internal_notes]
|
|
2871
|
+
properties:
|
|
2872
|
+
notes:
|
|
2873
|
+
description: Customer-visible note.
|
|
2874
|
+
type: string
|
|
2875
|
+
maxLength: 5000
|
|
2876
|
+
internal_notes:
|
|
2877
|
+
description: Staff-only note.
|
|
2878
|
+
type: string
|
|
2879
|
+
maxLength: 5000
|
|
2880
|
+
CancelBookingInput:
|
|
2881
|
+
type: object
|
|
2882
|
+
properties:
|
|
2883
|
+
reason:
|
|
2884
|
+
type: string
|
|
2885
|
+
maxLength: 500
|
|
2886
|
+
RescheduleBookingInput:
|
|
2887
|
+
type: object
|
|
2888
|
+
required: [new_start_ts]
|
|
2889
|
+
properties:
|
|
2890
|
+
new_start_ts:
|
|
2891
|
+
$ref: "#/components/schemas/BookingTimestampInput"
|
|
2892
|
+
new_resource_id:
|
|
2893
|
+
type: string
|
|
2894
|
+
BookingsPagination:
|
|
2895
|
+
description: >-
|
|
2896
|
+
Pagination for a bookings page. `truncated` is the extra statement:
|
|
2897
|
+
the underlying read is capped, and when the cap binds there are
|
|
2898
|
+
matching bookings no cursor from this call reaches — narrow the window.
|
|
2899
|
+
type: object
|
|
2900
|
+
required: [has_more, next_cursor, truncated]
|
|
2901
|
+
properties:
|
|
2902
|
+
has_more:
|
|
2903
|
+
type: boolean
|
|
2904
|
+
next_cursor:
|
|
2905
|
+
type: [string, "null"]
|
|
2906
|
+
truncated:
|
|
2907
|
+
type: boolean
|
|
2054
2908
|
GdprExport:
|
|
2055
2909
|
type: object
|
|
2056
2910
|
required: [id, request_type, status, submitted_at, completed_at]
|
|
@@ -2743,6 +3597,24 @@ components:
|
|
|
2743
3597
|
$ref: "#/components/schemas/Envelope_DealUpdateResult"
|
|
2744
3598
|
ApiResponse_DealRemoveResult:
|
|
2745
3599
|
$ref: "#/components/schemas/Envelope_DealRemoveResult"
|
|
3600
|
+
ApiResponse_Booking:
|
|
3601
|
+
$ref: "#/components/schemas/Envelope_Booking"
|
|
3602
|
+
ApiResponse_BookingServiceArray:
|
|
3603
|
+
$ref: "#/components/schemas/Envelope_BookingServiceArray"
|
|
3604
|
+
ApiResponse_BookingResourceArray:
|
|
3605
|
+
$ref: "#/components/schemas/Envelope_BookingResourceArray"
|
|
3606
|
+
ApiResponse_BookingSlotArray:
|
|
3607
|
+
$ref: "#/components/schemas/Envelope_BookingSlotArray"
|
|
3608
|
+
ApiResponse_BookingScheduleDayArray:
|
|
3609
|
+
$ref: "#/components/schemas/Envelope_BookingScheduleDayArray"
|
|
3610
|
+
ApiResponse_BookingCreateResult:
|
|
3611
|
+
$ref: "#/components/schemas/Envelope_BookingCreateResult"
|
|
3612
|
+
ApiResponse_BookingActionResult:
|
|
3613
|
+
$ref: "#/components/schemas/Envelope_BookingActionResult"
|
|
3614
|
+
ApiResponse_BookingRescheduleResult:
|
|
3615
|
+
$ref: "#/components/schemas/Envelope_BookingRescheduleResult"
|
|
3616
|
+
ApiResponse_ManageSummary:
|
|
3617
|
+
$ref: "#/components/schemas/Envelope_ManageSummary"
|
|
2746
3618
|
ApiResponse_GdprExportRequest:
|
|
2747
3619
|
$ref: "#/components/schemas/Envelope_GdprExportRequest"
|
|
2748
3620
|
ApiResponse_GdprExportArray:
|
|
@@ -2832,6 +3704,16 @@ components:
|
|
|
2832
3704
|
$ref: "#/components/schemas/Deal"
|
|
2833
3705
|
pagination:
|
|
2834
3706
|
$ref: "#/components/schemas/Pagination"
|
|
3707
|
+
PaginatedResponse_Booking:
|
|
3708
|
+
type: object
|
|
3709
|
+
required: [data, pagination]
|
|
3710
|
+
properties:
|
|
3711
|
+
data:
|
|
3712
|
+
type: array
|
|
3713
|
+
items:
|
|
3714
|
+
$ref: "#/components/schemas/Booking"
|
|
3715
|
+
pagination:
|
|
3716
|
+
$ref: "#/components/schemas/BookingsPagination"
|
|
2835
3717
|
PaginatedResponse_HelpdeskConversation:
|
|
2836
3718
|
type: object
|
|
2837
3719
|
required: [data, pagination]
|
|
@@ -3002,6 +3884,68 @@ components:
|
|
|
3002
3884
|
properties:
|
|
3003
3885
|
data:
|
|
3004
3886
|
$ref: "#/components/schemas/DealRemoveResult"
|
|
3887
|
+
Envelope_Booking:
|
|
3888
|
+
type: object
|
|
3889
|
+
required: [data]
|
|
3890
|
+
properties:
|
|
3891
|
+
data:
|
|
3892
|
+
$ref: "#/components/schemas/Booking"
|
|
3893
|
+
Envelope_BookingServiceArray:
|
|
3894
|
+
type: object
|
|
3895
|
+
required: [data]
|
|
3896
|
+
properties:
|
|
3897
|
+
data:
|
|
3898
|
+
type: array
|
|
3899
|
+
items:
|
|
3900
|
+
$ref: "#/components/schemas/BookingService"
|
|
3901
|
+
Envelope_BookingResourceArray:
|
|
3902
|
+
type: object
|
|
3903
|
+
required: [data]
|
|
3904
|
+
properties:
|
|
3905
|
+
data:
|
|
3906
|
+
type: array
|
|
3907
|
+
items:
|
|
3908
|
+
$ref: "#/components/schemas/BookingResource"
|
|
3909
|
+
Envelope_BookingSlotArray:
|
|
3910
|
+
type: object
|
|
3911
|
+
required: [data]
|
|
3912
|
+
properties:
|
|
3913
|
+
data:
|
|
3914
|
+
type: array
|
|
3915
|
+
items:
|
|
3916
|
+
$ref: "#/components/schemas/BookingSlot"
|
|
3917
|
+
Envelope_BookingScheduleDayArray:
|
|
3918
|
+
type: object
|
|
3919
|
+
required: [data]
|
|
3920
|
+
properties:
|
|
3921
|
+
data:
|
|
3922
|
+
type: array
|
|
3923
|
+
items:
|
|
3924
|
+
$ref: "#/components/schemas/BookingScheduleDay"
|
|
3925
|
+
Envelope_BookingCreateResult:
|
|
3926
|
+
type: object
|
|
3927
|
+
required: [data]
|
|
3928
|
+
properties:
|
|
3929
|
+
data:
|
|
3930
|
+
$ref: "#/components/schemas/BookingCreateResult"
|
|
3931
|
+
Envelope_BookingActionResult:
|
|
3932
|
+
type: object
|
|
3933
|
+
required: [data]
|
|
3934
|
+
properties:
|
|
3935
|
+
data:
|
|
3936
|
+
$ref: "#/components/schemas/BookingActionResult"
|
|
3937
|
+
Envelope_BookingRescheduleResult:
|
|
3938
|
+
type: object
|
|
3939
|
+
required: [data]
|
|
3940
|
+
properties:
|
|
3941
|
+
data:
|
|
3942
|
+
$ref: "#/components/schemas/BookingRescheduleResult"
|
|
3943
|
+
Envelope_ManageSummary:
|
|
3944
|
+
type: object
|
|
3945
|
+
required: [data]
|
|
3946
|
+
properties:
|
|
3947
|
+
data:
|
|
3948
|
+
$ref: "#/components/schemas/ManageSummary"
|
|
3005
3949
|
ScanCreateInput:
|
|
3006
3950
|
type: object
|
|
3007
3951
|
description: Provide exactly one of `url`, `orgnr`, or `name`.
|