licensekit-ruby 0.1.0.alpha.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.
@@ -0,0 +1,4394 @@
1
+ openapi: 3.1.0
2
+ info:
3
+ title: Open License API
4
+ version: 0.1.0
5
+ description: |
6
+ Open License locked `v1 core` API contract.
7
+
8
+ Management responses are JSON envelopes shaped as `{data, meta}`.
9
+ Signed runtime responses are JSON envelopes shaped as `{data, signature, meta}`.
10
+ Management operations advertise least-privilege token requirements via `x-required-scopes`.
11
+ `204 No Content` responses intentionally return an empty body.
12
+ license:
13
+ name: See project licensing terms
14
+ servers:
15
+ - url: /
16
+ tags:
17
+ - name: runtime
18
+ description: Public license runtime operations.
19
+ - name: products
20
+ description: Management operations for products.
21
+ - name: policies
22
+ description: Management operations for policies.
23
+ - name: features
24
+ description: Management operations for product features.
25
+ - name: customers
26
+ description: Management operations for customers.
27
+ - name: api-keys
28
+ description: Management operations for scoped API keys.
29
+ - name: events
30
+ description: Management operations for audit and event feeds.
31
+ - name: webhooks
32
+ description: Management operations for webhook endpoints and delivery state.
33
+ - name: licenses
34
+ description: Management operations for license lifecycle and assignments.
35
+ - name: devices
36
+ description: Management operations for registered license devices.
37
+ - name: commerce
38
+ description: Management operations for order and subscription records.
39
+ - name: custom-fields
40
+ description: Management operations for custom field definitions and values.
41
+ - name: versions
42
+ description: Management operations for product versions.
43
+ - name: system
44
+ description: Public health and signing-key endpoints.
45
+ components:
46
+ securitySchemes:
47
+ bearerAuth:
48
+ type: http
49
+ scheme: bearer
50
+ description: "Management API tokens are sent as `Authorization: Bearer <token>`."
51
+ licenseAuth:
52
+ type: apiKey
53
+ in: header
54
+ name: Authorization
55
+ description: "License runtime requests send credentials as `Authorization: License <license-key>`."
56
+ parameters:
57
+ IDPath:
58
+ in: path
59
+ name: id
60
+ required: true
61
+ schema:
62
+ type: string
63
+ FieldIDPath:
64
+ in: path
65
+ name: field_id
66
+ required: true
67
+ schema:
68
+ type: string
69
+ FeatureIDPath:
70
+ in: path
71
+ name: feature_id
72
+ required: true
73
+ schema:
74
+ type: string
75
+ DeviceIDPath:
76
+ in: path
77
+ name: device_id
78
+ required: true
79
+ schema:
80
+ type: string
81
+ LimitParam:
82
+ in: query
83
+ name: limit
84
+ description: Defaults to `50` and is clamped to `200`.
85
+ schema:
86
+ type: integer
87
+ minimum: 1
88
+ maximum: 200
89
+ CursorParam:
90
+ in: query
91
+ name: cursor
92
+ description: Return events with sequence numbers lower than this cursor.
93
+ schema:
94
+ type: integer
95
+ format: int64
96
+ minimum: 1
97
+ IdempotencyKeyHeader:
98
+ in: header
99
+ name: Idempotency-Key
100
+ required: true
101
+ schema:
102
+ type: string
103
+ responses:
104
+ BadRequest:
105
+ description: Invalid request syntax.
106
+ content:
107
+ application/json:
108
+ schema:
109
+ $ref: "#/components/schemas/ErrorEnvelope"
110
+ InvalidJSON:
111
+ description: Request body was invalid JSON or included unknown fields.
112
+ content:
113
+ application/json:
114
+ schema:
115
+ $ref: "#/components/schemas/ErrorEnvelope"
116
+ InvalidQuery:
117
+ description: Query parameters were invalid.
118
+ content:
119
+ application/json:
120
+ schema:
121
+ $ref: "#/components/schemas/ErrorEnvelope"
122
+ UnauthorizedManagement:
123
+ description: Missing, malformed, expired, inactive, CIDR-blocked, or unknown management token.
124
+ content:
125
+ application/json:
126
+ schema:
127
+ $ref: "#/components/schemas/ErrorEnvelope"
128
+ UnauthorizedLicense:
129
+ description: Missing or invalid license credentials.
130
+ content:
131
+ application/json:
132
+ schema:
133
+ $ref: "#/components/schemas/ErrorEnvelope"
134
+ ForbiddenScope:
135
+ description: The management token does not have a required scope for this operation. See the operation-level `x-required-scopes` extension; `admin` also satisfies all management operations.
136
+ content:
137
+ application/json:
138
+ schema:
139
+ $ref: "#/components/schemas/ErrorEnvelope"
140
+ ForbiddenRuntime:
141
+ description: The current license, device, policy, or version-eligibility state forbids the operation.
142
+ content:
143
+ application/json:
144
+ schema:
145
+ $ref: "#/components/schemas/ErrorEnvelope"
146
+ NotFound:
147
+ description: The requested resource was not found.
148
+ content:
149
+ application/json:
150
+ schema:
151
+ $ref: "#/components/schemas/ErrorEnvelope"
152
+ Conflict:
153
+ description: The request conflicts with current state or an existing record.
154
+ content:
155
+ application/json:
156
+ schema:
157
+ $ref: "#/components/schemas/ErrorEnvelope"
158
+ ValidationError:
159
+ description: The request body passed JSON decoding but failed business validation.
160
+ content:
161
+ application/json:
162
+ schema:
163
+ $ref: "#/components/schemas/ErrorEnvelope"
164
+ schemas:
165
+ ResponseMeta:
166
+ type: object
167
+ required:
168
+ - request_id
169
+ - timestamp
170
+ properties:
171
+ request_id:
172
+ type: string
173
+ timestamp:
174
+ type: string
175
+ format: date-time
176
+ ErrorObject:
177
+ type: object
178
+ required:
179
+ - code
180
+ - message
181
+ properties:
182
+ code:
183
+ type: string
184
+ message:
185
+ type: string
186
+ detail:
187
+ type: string
188
+ ErrorEnvelope:
189
+ type: object
190
+ required:
191
+ - error
192
+ - meta
193
+ properties:
194
+ error:
195
+ $ref: "#/components/schemas/ErrorObject"
196
+ meta:
197
+ $ref: "#/components/schemas/ResponseMeta"
198
+ EventPageInfo:
199
+ type: object
200
+ required:
201
+ - next_cursor
202
+ properties:
203
+ next_cursor:
204
+ type:
205
+ - integer
206
+ - "null"
207
+ format: int64
208
+ ManagementScope:
209
+ type: string
210
+ enum:
211
+ - admin
212
+ - product:read
213
+ - product:write
214
+ - license:read
215
+ - license:write
216
+ - device:write
217
+ - event:read
218
+ - webhook:write
219
+ LicenseType:
220
+ type: string
221
+ enum:
222
+ - perpetual
223
+ - time_limited
224
+ - subscription
225
+ - trial
226
+ - consumption
227
+ LicenseStatus:
228
+ type: string
229
+ enum:
230
+ - active
231
+ - suspended
232
+ - expired
233
+ - revoked
234
+ - grace_period
235
+ SubscriptionStatus:
236
+ type: string
237
+ enum:
238
+ - trialing
239
+ - active
240
+ - past_due
241
+ - paused
242
+ - canceled
243
+ OrderStatus:
244
+ type: string
245
+ enum:
246
+ - pending
247
+ - paid
248
+ - fulfilled
249
+ - canceled
250
+ - refunded
251
+ DeviceStatus:
252
+ type: string
253
+ enum:
254
+ - active
255
+ - deactivated
256
+ - blacklisted
257
+ - reset
258
+ - expired
259
+ DeviceBindingKind:
260
+ type: string
261
+ enum:
262
+ - hardware
263
+ - container
264
+ AuditActorType:
265
+ type: string
266
+ enum:
267
+ - api_key
268
+ - license
269
+ - oidc_subject
270
+ - system
271
+ CustomFieldResourceType:
272
+ type: string
273
+ enum:
274
+ - license
275
+ - customer
276
+ CustomFieldValueType:
277
+ type: string
278
+ enum:
279
+ - string
280
+ - integer
281
+ - boolean
282
+ - datetime
283
+ - enum
284
+ Signature:
285
+ type: object
286
+ required:
287
+ - alg
288
+ - kid
289
+ - value
290
+ properties:
291
+ alg:
292
+ type: string
293
+ kid:
294
+ type: string
295
+ value:
296
+ type: string
297
+ description: Base64-encoded signature over the JSON `data` payload.
298
+ PublicKey:
299
+ type: object
300
+ required:
301
+ - kid
302
+ - algorithm
303
+ - public_key
304
+ - status
305
+ - created_at
306
+ properties:
307
+ kid:
308
+ type: string
309
+ algorithm:
310
+ type: string
311
+ public_key:
312
+ type: string
313
+ description: Base64-encoded Ed25519 public key bytes.
314
+ status:
315
+ type: string
316
+ enum:
317
+ - active
318
+ - retired
319
+ created_at:
320
+ type: string
321
+ format: date-time
322
+ Product:
323
+ type: object
324
+ required:
325
+ - id
326
+ - name
327
+ - code
328
+ - metadata
329
+ - created_at
330
+ - updated_at
331
+ properties:
332
+ id:
333
+ type: string
334
+ name:
335
+ type: string
336
+ code:
337
+ type: string
338
+ metadata:
339
+ type: object
340
+ additionalProperties: true
341
+ created_at:
342
+ type: string
343
+ format: date-time
344
+ updated_at:
345
+ type: string
346
+ format: date-time
347
+ ProductCreateRequest:
348
+ type: object
349
+ additionalProperties: false
350
+ required:
351
+ - name
352
+ - code
353
+ properties:
354
+ name:
355
+ type: string
356
+ code:
357
+ type: string
358
+ metadata:
359
+ type: object
360
+ additionalProperties: true
361
+ ProductUpdateRequest:
362
+ type: object
363
+ additionalProperties: false
364
+ properties:
365
+ name:
366
+ type: string
367
+ code:
368
+ type: string
369
+ metadata:
370
+ type: object
371
+ additionalProperties: true
372
+ Policy:
373
+ type: object
374
+ required:
375
+ - id
376
+ - product_id
377
+ - name
378
+ - code
379
+ - license_type
380
+ - max_activations
381
+ - floating_timeout_minutes
382
+ - grace_period_days
383
+ - validation_interval_minutes
384
+ - require_heartbeat
385
+ - allow_offline_activation
386
+ - offline_grace_days
387
+ - allow_vm
388
+ - allow_container
389
+ - max_transfers
390
+ - metadata
391
+ - created_at
392
+ - updated_at
393
+ properties:
394
+ id:
395
+ type: string
396
+ product_id:
397
+ type: string
398
+ name:
399
+ type: string
400
+ code:
401
+ type: string
402
+ license_type:
403
+ $ref: "#/components/schemas/LicenseType"
404
+ max_activations:
405
+ type: integer
406
+ max_floating_users:
407
+ type: integer
408
+ max_container_instances:
409
+ type: integer
410
+ floating_timeout_minutes:
411
+ type: integer
412
+ grace_period_days:
413
+ type: integer
414
+ validation_interval_minutes:
415
+ type: integer
416
+ require_heartbeat:
417
+ type: boolean
418
+ allow_offline_activation:
419
+ type: boolean
420
+ offline_grace_days:
421
+ type: integer
422
+ allow_vm:
423
+ type: boolean
424
+ allow_container:
425
+ type: boolean
426
+ max_transfers:
427
+ type: integer
428
+ metadata:
429
+ type: object
430
+ additionalProperties: true
431
+ created_at:
432
+ type: string
433
+ format: date-time
434
+ updated_at:
435
+ type: string
436
+ format: date-time
437
+ PolicyCreateRequest:
438
+ type: object
439
+ additionalProperties: false
440
+ required:
441
+ - name
442
+ - code
443
+ - license_type
444
+ properties:
445
+ name:
446
+ type: string
447
+ code:
448
+ type: string
449
+ license_type:
450
+ $ref: "#/components/schemas/LicenseType"
451
+ max_floating_users:
452
+ type: integer
453
+ minimum: 0
454
+ floating_timeout_minutes:
455
+ type: integer
456
+ minimum: 1
457
+ require_heartbeat:
458
+ type: boolean
459
+ metadata:
460
+ type: object
461
+ additionalProperties: true
462
+ PolicyUpdateRequest:
463
+ type: object
464
+ additionalProperties: false
465
+ properties:
466
+ name:
467
+ type: string
468
+ code:
469
+ type: string
470
+ license_type:
471
+ $ref: "#/components/schemas/LicenseType"
472
+ max_floating_users:
473
+ type: integer
474
+ minimum: 0
475
+ floating_timeout_minutes:
476
+ type: integer
477
+ minimum: 1
478
+ require_heartbeat:
479
+ type: boolean
480
+ metadata:
481
+ type: object
482
+ additionalProperties: true
483
+ Feature:
484
+ type: object
485
+ required:
486
+ - id
487
+ - product_id
488
+ - code
489
+ - name
490
+ - metadata
491
+ - created_at
492
+ properties:
493
+ id:
494
+ type: string
495
+ product_id:
496
+ type: string
497
+ code:
498
+ type: string
499
+ name:
500
+ type: string
501
+ metadata:
502
+ type: object
503
+ additionalProperties: true
504
+ created_at:
505
+ type: string
506
+ format: date-time
507
+ FeatureCreateRequest:
508
+ type: object
509
+ additionalProperties: false
510
+ required:
511
+ - name
512
+ - code
513
+ properties:
514
+ name:
515
+ type: string
516
+ code:
517
+ type: string
518
+ metadata:
519
+ type: object
520
+ additionalProperties: true
521
+ Customer:
522
+ type: object
523
+ required:
524
+ - id
525
+ - name
526
+ - code
527
+ - metadata
528
+ - created_at
529
+ - updated_at
530
+ properties:
531
+ id:
532
+ type: string
533
+ name:
534
+ type: string
535
+ code:
536
+ type: string
537
+ email:
538
+ type: string
539
+ metadata:
540
+ type: object
541
+ additionalProperties: true
542
+ created_at:
543
+ type: string
544
+ format: date-time
545
+ updated_at:
546
+ type: string
547
+ format: date-time
548
+ CustomerCreateRequest:
549
+ type: object
550
+ additionalProperties: false
551
+ required:
552
+ - name
553
+ - code
554
+ properties:
555
+ name:
556
+ type: string
557
+ code:
558
+ type: string
559
+ email:
560
+ type: string
561
+ metadata:
562
+ type: object
563
+ additionalProperties: true
564
+ CustomerUpdateRequest:
565
+ type: object
566
+ additionalProperties: false
567
+ properties:
568
+ name:
569
+ type: string
570
+ code:
571
+ type: string
572
+ email:
573
+ type: string
574
+ metadata:
575
+ type: object
576
+ additionalProperties: true
577
+ APIKey:
578
+ type: object
579
+ required:
580
+ - id
581
+ - name
582
+ - key_prefix
583
+ - scopes
584
+ - allowed_cidrs
585
+ - is_active
586
+ - created_at
587
+ properties:
588
+ id:
589
+ type: string
590
+ name:
591
+ type: string
592
+ key_prefix:
593
+ type: string
594
+ scopes:
595
+ type: array
596
+ items:
597
+ $ref: "#/components/schemas/ManagementScope"
598
+ allowed_cidrs:
599
+ type: array
600
+ items:
601
+ type: string
602
+ is_active:
603
+ type: boolean
604
+ expires_at:
605
+ type: string
606
+ format: date-time
607
+ last_used_at:
608
+ type: string
609
+ format: date-time
610
+ created_at:
611
+ type: string
612
+ format: date-time
613
+ APIKeyCreateRequest:
614
+ type: object
615
+ additionalProperties: false
616
+ required:
617
+ - name
618
+ properties:
619
+ name:
620
+ type: string
621
+ scopes:
622
+ type: array
623
+ description: Defaults to `["admin"]` when omitted.
624
+ items:
625
+ $ref: "#/components/schemas/ManagementScope"
626
+ allowed_cidrs:
627
+ type: array
628
+ items:
629
+ type: string
630
+ expires_at:
631
+ type: string
632
+ format: date-time
633
+ APIKeyCreateResponse:
634
+ type: object
635
+ required:
636
+ - api_key
637
+ - token
638
+ properties:
639
+ api_key:
640
+ $ref: "#/components/schemas/APIKey"
641
+ token:
642
+ type: string
643
+ ProductVersion:
644
+ type: object
645
+ required:
646
+ - id
647
+ - product_id
648
+ - version
649
+ - released_at
650
+ - metadata
651
+ - created_at
652
+ - updated_at
653
+ properties:
654
+ id:
655
+ type: string
656
+ product_id:
657
+ type: string
658
+ version:
659
+ type: string
660
+ released_at:
661
+ type: string
662
+ format: date-time
663
+ metadata:
664
+ type: object
665
+ additionalProperties: true
666
+ created_at:
667
+ type: string
668
+ format: date-time
669
+ updated_at:
670
+ type: string
671
+ format: date-time
672
+ ProductVersionCreateRequest:
673
+ type: object
674
+ additionalProperties: false
675
+ required:
676
+ - version
677
+ properties:
678
+ version:
679
+ type: string
680
+ released_at:
681
+ type: string
682
+ format: date-time
683
+ description: Defaults to the current server time when omitted.
684
+ metadata:
685
+ type: object
686
+ additionalProperties: true
687
+ Subscription:
688
+ type: object
689
+ required:
690
+ - id
691
+ - product_id
692
+ - external_system
693
+ - external_id
694
+ - status
695
+ - current_period_start
696
+ - current_period_end
697
+ - cancel_at_period_end
698
+ - metadata
699
+ - created_at
700
+ - updated_at
701
+ properties:
702
+ id:
703
+ type: string
704
+ product_id:
705
+ type: string
706
+ customer_id:
707
+ type: string
708
+ external_system:
709
+ type: string
710
+ external_id:
711
+ type: string
712
+ status:
713
+ $ref: "#/components/schemas/SubscriptionStatus"
714
+ current_period_start:
715
+ type: string
716
+ format: date-time
717
+ current_period_end:
718
+ type: string
719
+ format: date-time
720
+ cancel_at_period_end:
721
+ type: boolean
722
+ canceled_at:
723
+ type: string
724
+ format: date-time
725
+ metadata:
726
+ type: object
727
+ additionalProperties: true
728
+ created_at:
729
+ type: string
730
+ format: date-time
731
+ updated_at:
732
+ type: string
733
+ format: date-time
734
+ SubscriptionCreateRequest:
735
+ type: object
736
+ additionalProperties: false
737
+ required:
738
+ - external_system
739
+ - external_id
740
+ - status
741
+ - current_period_start
742
+ - current_period_end
743
+ properties:
744
+ customer_id:
745
+ type: string
746
+ external_system:
747
+ type: string
748
+ external_id:
749
+ type: string
750
+ status:
751
+ $ref: "#/components/schemas/SubscriptionStatus"
752
+ current_period_start:
753
+ type: string
754
+ format: date-time
755
+ current_period_end:
756
+ type: string
757
+ format: date-time
758
+ cancel_at_period_end:
759
+ type: boolean
760
+ description: Defaults to `false`.
761
+ canceled_at:
762
+ type: string
763
+ format: date-time
764
+ description: Allowed only when `status` is `canceled`.
765
+ metadata:
766
+ type: object
767
+ additionalProperties: true
768
+ SubscriptionUpdateRequest:
769
+ type: object
770
+ additionalProperties: false
771
+ properties:
772
+ customer_id:
773
+ type: string
774
+ description: Send an empty string to clear the current link.
775
+ external_system:
776
+ type: string
777
+ external_id:
778
+ type: string
779
+ status:
780
+ $ref: "#/components/schemas/SubscriptionStatus"
781
+ current_period_start:
782
+ type: string
783
+ format: date-time
784
+ current_period_end:
785
+ type: string
786
+ format: date-time
787
+ cancel_at_period_end:
788
+ type: boolean
789
+ canceled_at:
790
+ type: string
791
+ format: date-time
792
+ metadata:
793
+ type: object
794
+ additionalProperties: true
795
+ Order:
796
+ type: object
797
+ required:
798
+ - id
799
+ - product_id
800
+ - external_system
801
+ - external_id
802
+ - status
803
+ - metadata
804
+ - created_at
805
+ - updated_at
806
+ properties:
807
+ id:
808
+ type: string
809
+ product_id:
810
+ type: string
811
+ customer_id:
812
+ type: string
813
+ subscription_id:
814
+ type: string
815
+ external_system:
816
+ type: string
817
+ external_id:
818
+ type: string
819
+ status:
820
+ $ref: "#/components/schemas/OrderStatus"
821
+ period_start:
822
+ type: string
823
+ format: date-time
824
+ period_end:
825
+ type: string
826
+ format: date-time
827
+ metadata:
828
+ type: object
829
+ additionalProperties: true
830
+ created_at:
831
+ type: string
832
+ format: date-time
833
+ updated_at:
834
+ type: string
835
+ format: date-time
836
+ OrderCreateRequest:
837
+ type: object
838
+ additionalProperties: false
839
+ required:
840
+ - external_system
841
+ - external_id
842
+ - status
843
+ properties:
844
+ customer_id:
845
+ type: string
846
+ subscription_id:
847
+ type: string
848
+ external_system:
849
+ type: string
850
+ external_id:
851
+ type: string
852
+ status:
853
+ $ref: "#/components/schemas/OrderStatus"
854
+ period_start:
855
+ type: string
856
+ format: date-time
857
+ description: Must be provided together with `period_end`.
858
+ period_end:
859
+ type: string
860
+ format: date-time
861
+ description: Must be provided together with `period_start`.
862
+ metadata:
863
+ type: object
864
+ additionalProperties: true
865
+ OrderUpdateRequest:
866
+ type: object
867
+ additionalProperties: false
868
+ properties:
869
+ customer_id:
870
+ type: string
871
+ description: Send an empty string to clear the current link.
872
+ subscription_id:
873
+ type: string
874
+ description: Send an empty string to clear the current link.
875
+ external_system:
876
+ type: string
877
+ external_id:
878
+ type: string
879
+ status:
880
+ $ref: "#/components/schemas/OrderStatus"
881
+ period_start:
882
+ type: string
883
+ format: date-time
884
+ period_end:
885
+ type: string
886
+ format: date-time
887
+ metadata:
888
+ type: object
889
+ additionalProperties: true
890
+ CustomFieldDefinition:
891
+ type: object
892
+ required:
893
+ - id
894
+ - product_id
895
+ - resource_type
896
+ - code
897
+ - name
898
+ - value_type
899
+ - is_required
900
+ - enum_options
901
+ - metadata
902
+ - created_at
903
+ - updated_at
904
+ properties:
905
+ id:
906
+ type: string
907
+ product_id:
908
+ type: string
909
+ resource_type:
910
+ $ref: "#/components/schemas/CustomFieldResourceType"
911
+ code:
912
+ type: string
913
+ name:
914
+ type: string
915
+ value_type:
916
+ $ref: "#/components/schemas/CustomFieldValueType"
917
+ is_required:
918
+ type: boolean
919
+ enum_options:
920
+ type: array
921
+ items:
922
+ type: string
923
+ metadata:
924
+ type: object
925
+ additionalProperties: true
926
+ created_at:
927
+ type: string
928
+ format: date-time
929
+ updated_at:
930
+ type: string
931
+ format: date-time
932
+ CustomFieldDefinitionCreateRequest:
933
+ type: object
934
+ additionalProperties: false
935
+ required:
936
+ - resource_type
937
+ - code
938
+ - name
939
+ - value_type
940
+ properties:
941
+ resource_type:
942
+ $ref: "#/components/schemas/CustomFieldResourceType"
943
+ code:
944
+ type: string
945
+ name:
946
+ type: string
947
+ value_type:
948
+ $ref: "#/components/schemas/CustomFieldValueType"
949
+ is_required:
950
+ type: boolean
951
+ enum_options:
952
+ type: array
953
+ items:
954
+ type: string
955
+ metadata:
956
+ type: object
957
+ additionalProperties: true
958
+ CustomFieldDefinitionUpdateRequest:
959
+ type: object
960
+ additionalProperties: false
961
+ properties:
962
+ code:
963
+ type: string
964
+ name:
965
+ type: string
966
+ is_required:
967
+ type: boolean
968
+ enum_options:
969
+ type: array
970
+ items:
971
+ type: string
972
+ metadata:
973
+ type: object
974
+ additionalProperties: true
975
+ CustomFieldValue:
976
+ type: object
977
+ required:
978
+ - definition_id
979
+ - product_id
980
+ - resource_type
981
+ - resource_id
982
+ - code
983
+ - name
984
+ - value_type
985
+ - is_required
986
+ - enum_options
987
+ - metadata
988
+ - updated_at
989
+ properties:
990
+ definition_id:
991
+ type: string
992
+ product_id:
993
+ type: string
994
+ resource_type:
995
+ $ref: "#/components/schemas/CustomFieldResourceType"
996
+ resource_id:
997
+ type: string
998
+ code:
999
+ type: string
1000
+ name:
1001
+ type: string
1002
+ value_type:
1003
+ $ref: "#/components/schemas/CustomFieldValueType"
1004
+ is_required:
1005
+ type: boolean
1006
+ enum_options:
1007
+ type: array
1008
+ items:
1009
+ type: string
1010
+ metadata:
1011
+ type: object
1012
+ additionalProperties: true
1013
+ string_value:
1014
+ type: string
1015
+ integer_value:
1016
+ type: integer
1017
+ format: int64
1018
+ boolean_value:
1019
+ type: boolean
1020
+ datetime_value:
1021
+ type: string
1022
+ format: date-time
1023
+ enum_value:
1024
+ type: string
1025
+ updated_at:
1026
+ type: string
1027
+ format: date-time
1028
+ CustomFieldValueUpsertRequest:
1029
+ type: object
1030
+ additionalProperties: false
1031
+ description: Provide exactly one typed value, or set `clear` to true.
1032
+ properties:
1033
+ clear:
1034
+ type: boolean
1035
+ string_value:
1036
+ type: string
1037
+ integer_value:
1038
+ type: integer
1039
+ format: int64
1040
+ boolean_value:
1041
+ type: boolean
1042
+ datetime_value:
1043
+ type: string
1044
+ format: date-time
1045
+ enum_value:
1046
+ type: string
1047
+ License:
1048
+ type: object
1049
+ required:
1050
+ - id
1051
+ - product_id
1052
+ - policy_id
1053
+ - status
1054
+ - license_key_prefix
1055
+ - license_key_last4
1056
+ - active_device_count
1057
+ - times_activated
1058
+ - times_transferred
1059
+ - total_consumptions
1060
+ - entitlement_version
1061
+ - metadata
1062
+ - created_at
1063
+ - updated_at
1064
+ properties:
1065
+ id:
1066
+ type: string
1067
+ product_id:
1068
+ type: string
1069
+ policy_id:
1070
+ type: string
1071
+ customer_id:
1072
+ type: string
1073
+ order_id:
1074
+ type: string
1075
+ subscription_id:
1076
+ type: string
1077
+ status:
1078
+ $ref: "#/components/schemas/LicenseStatus"
1079
+ license_key_prefix:
1080
+ type: string
1081
+ license_key_last4:
1082
+ type: string
1083
+ customer_email:
1084
+ type: string
1085
+ customer_name:
1086
+ type: string
1087
+ active_device_count:
1088
+ type: integer
1089
+ times_activated:
1090
+ type: integer
1091
+ times_transferred:
1092
+ type: integer
1093
+ total_consumptions:
1094
+ type: integer
1095
+ format: int64
1096
+ entitlement_version:
1097
+ type: integer
1098
+ format: int64
1099
+ starts_at:
1100
+ type: string
1101
+ format: date-time
1102
+ expires_at:
1103
+ type: string
1104
+ format: date-time
1105
+ maintenance_expires_at:
1106
+ type: string
1107
+ format: date-time
1108
+ description: Present only for perpetual licenses with a maintenance cutoff.
1109
+ metadata:
1110
+ type: object
1111
+ additionalProperties: true
1112
+ created_at:
1113
+ type: string
1114
+ format: date-time
1115
+ updated_at:
1116
+ type: string
1117
+ format: date-time
1118
+ LicenseCreateRequest:
1119
+ type: object
1120
+ additionalProperties: false
1121
+ required:
1122
+ - product_id
1123
+ - policy_id
1124
+ properties:
1125
+ product_id:
1126
+ type: string
1127
+ policy_id:
1128
+ type: string
1129
+ customer_id:
1130
+ type: string
1131
+ order_id:
1132
+ type: string
1133
+ description: |
1134
+ Optional origin order link. The order must belong to the same product.
1135
+ If it is already linked to a subscription and `subscription_id` is omitted,
1136
+ the subscription link is inferred and persisted on the license.
1137
+ subscription_id:
1138
+ type: string
1139
+ description: Optional origin subscription link. The subscription must belong to the same product.
1140
+ customer_email:
1141
+ type: string
1142
+ customer_name:
1143
+ type: string
1144
+ starts_at:
1145
+ type: string
1146
+ format: date-time
1147
+ expires_at:
1148
+ type: string
1149
+ format: date-time
1150
+ maintenance_expires_at:
1151
+ type: string
1152
+ format: date-time
1153
+ description: Supported only for perpetual licenses.
1154
+ metadata:
1155
+ type: object
1156
+ additionalProperties: true
1157
+ LicenseCreateResponse:
1158
+ type: object
1159
+ required:
1160
+ - license
1161
+ - license_key
1162
+ properties:
1163
+ license:
1164
+ $ref: "#/components/schemas/License"
1165
+ license_key:
1166
+ type: string
1167
+ LicenseRenewRequest:
1168
+ type: object
1169
+ additionalProperties: false
1170
+ description: |
1171
+ Provide exactly one of `expires_at` or `extend_by_days`.
1172
+ Renewal extends from the current stored expiry when the license is still active,
1173
+ otherwise it extends from the renewal time (`now`).
1174
+ properties:
1175
+ expires_at:
1176
+ type: string
1177
+ format: date-time
1178
+ extend_by_days:
1179
+ type: integer
1180
+ minimum: 1
1181
+ order_id:
1182
+ type: string
1183
+ description: |
1184
+ Optional renewal-source order. It is validated and recorded in audit metadata,
1185
+ but does not rewrite the stored origin linkage on the license.
1186
+ subscription_id:
1187
+ type: string
1188
+ description: |
1189
+ Optional renewal-source subscription. It is validated and recorded in audit metadata,
1190
+ but does not rewrite the stored origin linkage on the license.
1191
+ LicenseTransferRequest:
1192
+ type: object
1193
+ additionalProperties: false
1194
+ description: Provide at least one ownership field or set `reset_devices` to true.
1195
+ properties:
1196
+ customer_id:
1197
+ type: string
1198
+ description: Send an empty string to clear the current linked customer.
1199
+ customer_email:
1200
+ type: string
1201
+ customer_name:
1202
+ type: string
1203
+ reset_devices:
1204
+ type: boolean
1205
+ LicenseFeature:
1206
+ type: object
1207
+ required:
1208
+ - license_id
1209
+ - feature_id
1210
+ - feature_code
1211
+ - feature_name
1212
+ - enabled
1213
+ - total_consumptions
1214
+ - metadata
1215
+ properties:
1216
+ license_id:
1217
+ type: string
1218
+ feature_id:
1219
+ type: string
1220
+ feature_code:
1221
+ type: string
1222
+ feature_name:
1223
+ type: string
1224
+ enabled:
1225
+ type: boolean
1226
+ max_consumptions:
1227
+ type: integer
1228
+ format: int64
1229
+ total_consumptions:
1230
+ type: integer
1231
+ format: int64
1232
+ remaining:
1233
+ type: integer
1234
+ format: int64
1235
+ expires_at:
1236
+ type: string
1237
+ format: date-time
1238
+ metadata:
1239
+ type: object
1240
+ additionalProperties: true
1241
+ LicenseFeatureAssignRequest:
1242
+ type: object
1243
+ additionalProperties: false
1244
+ required:
1245
+ - feature_id
1246
+ properties:
1247
+ feature_id:
1248
+ type: string
1249
+ enabled:
1250
+ type: boolean
1251
+ max_consumptions:
1252
+ type: integer
1253
+ format: int64
1254
+ minimum: 0
1255
+ expires_at:
1256
+ type: string
1257
+ format: date-time
1258
+ metadata:
1259
+ type: object
1260
+ additionalProperties: true
1261
+ LicenseFeatureUsageResetRequest:
1262
+ type: object
1263
+ additionalProperties: false
1264
+ description: |
1265
+ Select the target assignment with exactly one of `feature_id` or `feature_code`.
1266
+ Then provide at least one usage mutation.
1267
+ properties:
1268
+ feature_id:
1269
+ type: string
1270
+ feature_code:
1271
+ type: string
1272
+ add_credits:
1273
+ type: integer
1274
+ format: int64
1275
+ minimum: 1
1276
+ max_consumptions:
1277
+ type: integer
1278
+ format: int64
1279
+ minimum: 0
1280
+ total_consumptions:
1281
+ type: integer
1282
+ format: int64
1283
+ minimum: 0
1284
+ reset_consumed:
1285
+ type: boolean
1286
+ Device:
1287
+ type: object
1288
+ required:
1289
+ - id
1290
+ - license_id
1291
+ - binding_kind
1292
+ - binding_key
1293
+ - is_vm
1294
+ - is_container
1295
+ - status
1296
+ - first_seen_at
1297
+ - last_seen_at
1298
+ - metadata
1299
+ - created_at
1300
+ - updated_at
1301
+ properties:
1302
+ id:
1303
+ type: string
1304
+ license_id:
1305
+ type: string
1306
+ binding_kind:
1307
+ $ref: "#/components/schemas/DeviceBindingKind"
1308
+ binding_key:
1309
+ type: string
1310
+ fingerprint:
1311
+ type: string
1312
+ hostname:
1313
+ type: string
1314
+ os:
1315
+ type: string
1316
+ ip_address:
1317
+ type: string
1318
+ is_vm:
1319
+ type: boolean
1320
+ is_container:
1321
+ type: boolean
1322
+ container_id:
1323
+ type: string
1324
+ cluster_id:
1325
+ type: string
1326
+ namespace:
1327
+ type: string
1328
+ pod_name:
1329
+ type: string
1330
+ status:
1331
+ $ref: "#/components/schemas/DeviceStatus"
1332
+ first_seen_at:
1333
+ type: string
1334
+ format: date-time
1335
+ last_seen_at:
1336
+ type: string
1337
+ format: date-time
1338
+ last_validated_at:
1339
+ type: string
1340
+ format: date-time
1341
+ metadata:
1342
+ type: object
1343
+ additionalProperties: true
1344
+ created_at:
1345
+ type: string
1346
+ format: date-time
1347
+ updated_at:
1348
+ type: string
1349
+ format: date-time
1350
+ Event:
1351
+ type: object
1352
+ required:
1353
+ - sequence
1354
+ - event_type
1355
+ - actor_type
1356
+ - actor_id
1357
+ - resource_type
1358
+ - metadata
1359
+ - created_at
1360
+ properties:
1361
+ sequence:
1362
+ type: integer
1363
+ format: int64
1364
+ event_type:
1365
+ type: string
1366
+ actor_type:
1367
+ $ref: "#/components/schemas/AuditActorType"
1368
+ actor_id:
1369
+ type: string
1370
+ resource_type:
1371
+ type: string
1372
+ resource_id:
1373
+ type: string
1374
+ metadata:
1375
+ type: object
1376
+ additionalProperties: true
1377
+ description: Audit metadata with sensitive runtime binding values redacted where applicable.
1378
+ ip_address:
1379
+ type: string
1380
+ created_at:
1381
+ type: string
1382
+ format: date-time
1383
+ WebhookEndpoint:
1384
+ type: object
1385
+ required:
1386
+ - id
1387
+ - name
1388
+ - url
1389
+ - secret_prefix
1390
+ - event_types
1391
+ - is_active
1392
+ - created_at
1393
+ - updated_at
1394
+ properties:
1395
+ id:
1396
+ type: string
1397
+ name:
1398
+ type: string
1399
+ url:
1400
+ type: string
1401
+ format: uri
1402
+ secret_prefix:
1403
+ type: string
1404
+ description: Prefix of the current shared secret. The full secret is returned only on create or rotation.
1405
+ event_types:
1406
+ type: array
1407
+ description: Empty means the endpoint receives all events.
1408
+ items:
1409
+ type: string
1410
+ is_active:
1411
+ type: boolean
1412
+ last_delivery_at:
1413
+ type: string
1414
+ format: date-time
1415
+ created_at:
1416
+ type: string
1417
+ format: date-time
1418
+ updated_at:
1419
+ type: string
1420
+ format: date-time
1421
+ WebhookEndpointCreateRequest:
1422
+ type: object
1423
+ additionalProperties: false
1424
+ required:
1425
+ - name
1426
+ - url
1427
+ properties:
1428
+ name:
1429
+ type: string
1430
+ url:
1431
+ type: string
1432
+ format: uri
1433
+ event_types:
1434
+ type: array
1435
+ items:
1436
+ type: string
1437
+ secret:
1438
+ type: string
1439
+ description: Optional custom shared secret. When omitted, the server generates one.
1440
+ is_active:
1441
+ type: boolean
1442
+ WebhookEndpointUpdateRequest:
1443
+ type: object
1444
+ additionalProperties: false
1445
+ properties:
1446
+ name:
1447
+ type: string
1448
+ url:
1449
+ type: string
1450
+ format: uri
1451
+ event_types:
1452
+ type: array
1453
+ description: Replaces the current allow-list. Send an empty array to subscribe to all events.
1454
+ items:
1455
+ type: string
1456
+ secret:
1457
+ type: string
1458
+ description: Replaces the current shared secret with the provided value.
1459
+ rotate_secret:
1460
+ type: boolean
1461
+ description: Generates and returns a new secret. Cannot be combined with `secret`.
1462
+ is_active:
1463
+ type: boolean
1464
+ WebhookEndpointWithSecret:
1465
+ type: object
1466
+ required:
1467
+ - webhook
1468
+ - secret
1469
+ properties:
1470
+ webhook:
1471
+ $ref: "#/components/schemas/WebhookEndpoint"
1472
+ secret:
1473
+ type: string
1474
+ FeatureEntitlement:
1475
+ type: object
1476
+ required:
1477
+ - code
1478
+ - enabled
1479
+ properties:
1480
+ code:
1481
+ type: string
1482
+ enabled:
1483
+ type: boolean
1484
+ quota:
1485
+ type: integer
1486
+ format: int64
1487
+ consumed:
1488
+ type: integer
1489
+ format: int64
1490
+ remaining:
1491
+ type: integer
1492
+ format: int64
1493
+ VersionEligibility:
1494
+ type: object
1495
+ required:
1496
+ - app_version
1497
+ - is_entitled
1498
+ - enforced
1499
+ properties:
1500
+ app_version:
1501
+ type: string
1502
+ is_entitled:
1503
+ type: boolean
1504
+ enforced:
1505
+ type: boolean
1506
+ description: False when the product has no version catalog yet, so version gating is not enforced.
1507
+ released_at:
1508
+ type: string
1509
+ format: date-time
1510
+ eligible_through:
1511
+ type: string
1512
+ format: date-time
1513
+ RuntimeBindingRequest:
1514
+ type: object
1515
+ additionalProperties: false
1516
+ description: |
1517
+ Hardware requests use `fingerprint` and leave `is_container` false.
1518
+ Container requests set `is_container` to true and must supply at least one of
1519
+ `cluster_id`, `namespace`, `pod_name`, or `container_id`.
1520
+ properties:
1521
+ fingerprint:
1522
+ type: string
1523
+ hostname:
1524
+ type: string
1525
+ os:
1526
+ type: string
1527
+ is_vm:
1528
+ type: boolean
1529
+ is_container:
1530
+ type: boolean
1531
+ container_id:
1532
+ type: string
1533
+ cluster_id:
1534
+ type: string
1535
+ namespace:
1536
+ type: string
1537
+ pod_name:
1538
+ type: string
1539
+ app_version:
1540
+ type: string
1541
+ ConsumeLicenseRequest:
1542
+ allOf:
1543
+ - $ref: "#/components/schemas/RuntimeBindingRequest"
1544
+ - type: object
1545
+ additionalProperties: false
1546
+ required:
1547
+ - feature_code
1548
+ - event_id
1549
+ properties:
1550
+ feature_code:
1551
+ type: string
1552
+ amount:
1553
+ type: integer
1554
+ format: int64
1555
+ minimum: 1
1556
+ description: Defaults to `1` when omitted.
1557
+ event_id:
1558
+ type: string
1559
+ FloatingLeaseRequest:
1560
+ type: object
1561
+ additionalProperties: false
1562
+ required:
1563
+ - lease_token
1564
+ properties:
1565
+ lease_token:
1566
+ type: string
1567
+ RuntimeEntitlementResponseData:
1568
+ type: object
1569
+ required:
1570
+ - license_id
1571
+ - status
1572
+ - license_type
1573
+ - entitlement_version
1574
+ - issued_at
1575
+ - next_check_at
1576
+ - device_id
1577
+ - features
1578
+ properties:
1579
+ license_id:
1580
+ type: string
1581
+ status:
1582
+ type: string
1583
+ license_type:
1584
+ $ref: "#/components/schemas/LicenseType"
1585
+ entitlement_version:
1586
+ type: integer
1587
+ format: int64
1588
+ issued_at:
1589
+ type: string
1590
+ format: date-time
1591
+ next_check_at:
1592
+ type: string
1593
+ format: date-time
1594
+ expires_at:
1595
+ type: string
1596
+ format: date-time
1597
+ device_id:
1598
+ type: string
1599
+ features:
1600
+ type: array
1601
+ items:
1602
+ $ref: "#/components/schemas/FeatureEntitlement"
1603
+ version_eligibility:
1604
+ $ref: "#/components/schemas/VersionEligibility"
1605
+ DeactivationResponseData:
1606
+ type: object
1607
+ required:
1608
+ - license_id
1609
+ - status
1610
+ - license_type
1611
+ - entitlement_version
1612
+ - issued_at
1613
+ - device_id
1614
+ properties:
1615
+ license_id:
1616
+ type: string
1617
+ status:
1618
+ type: string
1619
+ license_type:
1620
+ $ref: "#/components/schemas/LicenseType"
1621
+ entitlement_version:
1622
+ type: integer
1623
+ format: int64
1624
+ issued_at:
1625
+ type: string
1626
+ format: date-time
1627
+ device_id:
1628
+ type: string
1629
+ expires_at:
1630
+ type: string
1631
+ format: date-time
1632
+ FloatingCheckoutResponseData:
1633
+ type: object
1634
+ required:
1635
+ - license_id
1636
+ - status
1637
+ - license_type
1638
+ - entitlement_version
1639
+ - issued_at
1640
+ - device_id
1641
+ - lease_token
1642
+ - lease_expires_at
1643
+ - features
1644
+ properties:
1645
+ license_id:
1646
+ type: string
1647
+ status:
1648
+ type: string
1649
+ license_type:
1650
+ $ref: "#/components/schemas/LicenseType"
1651
+ entitlement_version:
1652
+ type: integer
1653
+ format: int64
1654
+ issued_at:
1655
+ type: string
1656
+ format: date-time
1657
+ expires_at:
1658
+ type: string
1659
+ format: date-time
1660
+ device_id:
1661
+ type: string
1662
+ lease_token:
1663
+ type: string
1664
+ lease_expires_at:
1665
+ type: string
1666
+ format: date-time
1667
+ features:
1668
+ type: array
1669
+ items:
1670
+ $ref: "#/components/schemas/FeatureEntitlement"
1671
+ version_eligibility:
1672
+ $ref: "#/components/schemas/VersionEligibility"
1673
+ FloatingLeaseResponseData:
1674
+ type: object
1675
+ required:
1676
+ - license_id
1677
+ - status
1678
+ - license_type
1679
+ - entitlement_version
1680
+ - issued_at
1681
+ - device_id
1682
+ - lease_expires_at
1683
+ properties:
1684
+ license_id:
1685
+ type: string
1686
+ status:
1687
+ type: string
1688
+ license_type:
1689
+ $ref: "#/components/schemas/LicenseType"
1690
+ entitlement_version:
1691
+ type: integer
1692
+ format: int64
1693
+ issued_at:
1694
+ type: string
1695
+ format: date-time
1696
+ expires_at:
1697
+ type: string
1698
+ format: date-time
1699
+ device_id:
1700
+ type: string
1701
+ lease_expires_at:
1702
+ type: string
1703
+ format: date-time
1704
+ features:
1705
+ type: array
1706
+ items:
1707
+ $ref: "#/components/schemas/FeatureEntitlement"
1708
+ version_eligibility:
1709
+ $ref: "#/components/schemas/VersionEligibility"
1710
+ OfflineEnvelope:
1711
+ type: object
1712
+ required:
1713
+ - kid
1714
+ - salt
1715
+ - nonce
1716
+ - ciphertext
1717
+ properties:
1718
+ kid:
1719
+ type: string
1720
+ salt:
1721
+ type: string
1722
+ description: Base64-encoded HKDF salt.
1723
+ nonce:
1724
+ type: string
1725
+ description: Base64-encoded AES-GCM nonce.
1726
+ ciphertext:
1727
+ type: string
1728
+ description: Base64-encoded encrypted signed payload envelope.
1729
+ SignedRuntimeEntitlementEnvelope:
1730
+ type: object
1731
+ required:
1732
+ - data
1733
+ - signature
1734
+ - meta
1735
+ properties:
1736
+ data:
1737
+ $ref: "#/components/schemas/RuntimeEntitlementResponseData"
1738
+ signature:
1739
+ $ref: "#/components/schemas/Signature"
1740
+ meta:
1741
+ $ref: "#/components/schemas/ResponseMeta"
1742
+ SignedRuntimeDeactivationEnvelope:
1743
+ type: object
1744
+ required:
1745
+ - data
1746
+ - signature
1747
+ - meta
1748
+ properties:
1749
+ data:
1750
+ $ref: "#/components/schemas/DeactivationResponseData"
1751
+ signature:
1752
+ $ref: "#/components/schemas/Signature"
1753
+ meta:
1754
+ $ref: "#/components/schemas/ResponseMeta"
1755
+ SignedRuntimeFloatingCheckoutEnvelope:
1756
+ type: object
1757
+ required:
1758
+ - data
1759
+ - signature
1760
+ - meta
1761
+ properties:
1762
+ data:
1763
+ $ref: "#/components/schemas/FloatingCheckoutResponseData"
1764
+ signature:
1765
+ $ref: "#/components/schemas/Signature"
1766
+ meta:
1767
+ $ref: "#/components/schemas/ResponseMeta"
1768
+ SignedRuntimeFloatingLeaseEnvelope:
1769
+ type: object
1770
+ required:
1771
+ - data
1772
+ - signature
1773
+ - meta
1774
+ properties:
1775
+ data:
1776
+ $ref: "#/components/schemas/FloatingLeaseResponseData"
1777
+ signature:
1778
+ $ref: "#/components/schemas/Signature"
1779
+ meta:
1780
+ $ref: "#/components/schemas/ResponseMeta"
1781
+ HealthData:
1782
+ type: object
1783
+ required:
1784
+ - status
1785
+ properties:
1786
+ status:
1787
+ type: string
1788
+ enum:
1789
+ - ok
1790
+ ReadyData:
1791
+ type: object
1792
+ required:
1793
+ - status
1794
+ - db
1795
+ properties:
1796
+ status:
1797
+ type: string
1798
+ enum:
1799
+ - ready
1800
+ - not_ready
1801
+ db:
1802
+ type: string
1803
+ paths:
1804
+ /api/v1/license/activate:
1805
+ post:
1806
+ operationId: activateLicense
1807
+ tags: [runtime]
1808
+ summary: Activate a license for a hardware or container binding
1809
+ description: |
1810
+ Returns the signed entitlement state for the requested binding.
1811
+ Verify `signature` against `/api/v1/system/public-keys`.
1812
+ security:
1813
+ - licenseAuth: []
1814
+ parameters:
1815
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
1816
+ requestBody:
1817
+ required: true
1818
+ content:
1819
+ application/json:
1820
+ schema:
1821
+ $ref: "#/components/schemas/RuntimeBindingRequest"
1822
+ responses:
1823
+ "200":
1824
+ description: Signed activation response.
1825
+ content:
1826
+ application/json:
1827
+ schema:
1828
+ $ref: "#/components/schemas/SignedRuntimeEntitlementEnvelope"
1829
+ "400":
1830
+ $ref: "#/components/responses/BadRequest"
1831
+ "401":
1832
+ $ref: "#/components/responses/UnauthorizedLicense"
1833
+ "403":
1834
+ $ref: "#/components/responses/ForbiddenRuntime"
1835
+ "409":
1836
+ $ref: "#/components/responses/Conflict"
1837
+ "422":
1838
+ $ref: "#/components/responses/ValidationError"
1839
+ /api/v1/license/validate:
1840
+ post:
1841
+ operationId: validateLicense
1842
+ tags: [runtime]
1843
+ summary: Validate a bound license and refresh validation timestamps
1844
+ security:
1845
+ - licenseAuth: []
1846
+ requestBody:
1847
+ required: true
1848
+ content:
1849
+ application/json:
1850
+ schema:
1851
+ $ref: "#/components/schemas/RuntimeBindingRequest"
1852
+ responses:
1853
+ "200":
1854
+ description: Signed validation response.
1855
+ content:
1856
+ application/json:
1857
+ schema:
1858
+ $ref: "#/components/schemas/SignedRuntimeEntitlementEnvelope"
1859
+ "400":
1860
+ $ref: "#/components/responses/InvalidJSON"
1861
+ "401":
1862
+ $ref: "#/components/responses/UnauthorizedLicense"
1863
+ "403":
1864
+ $ref: "#/components/responses/ForbiddenRuntime"
1865
+ "404":
1866
+ $ref: "#/components/responses/NotFound"
1867
+ "422":
1868
+ $ref: "#/components/responses/ValidationError"
1869
+ /api/v1/license/check:
1870
+ post:
1871
+ operationId: checkLicense
1872
+ tags: [runtime]
1873
+ summary: Check current entitlements without mutating validation timestamps
1874
+ security:
1875
+ - licenseAuth: []
1876
+ requestBody:
1877
+ required: true
1878
+ content:
1879
+ application/json:
1880
+ schema:
1881
+ $ref: "#/components/schemas/RuntimeBindingRequest"
1882
+ responses:
1883
+ "200":
1884
+ description: Signed entitlement response.
1885
+ content:
1886
+ application/json:
1887
+ schema:
1888
+ $ref: "#/components/schemas/SignedRuntimeEntitlementEnvelope"
1889
+ "400":
1890
+ $ref: "#/components/responses/InvalidJSON"
1891
+ "401":
1892
+ $ref: "#/components/responses/UnauthorizedLicense"
1893
+ "403":
1894
+ $ref: "#/components/responses/ForbiddenRuntime"
1895
+ "404":
1896
+ $ref: "#/components/responses/NotFound"
1897
+ "422":
1898
+ $ref: "#/components/responses/ValidationError"
1899
+ /api/v1/license/consume:
1900
+ post:
1901
+ operationId: consumeLicense
1902
+ tags: [runtime]
1903
+ summary: Consume metered feature usage for an active bound license
1904
+ security:
1905
+ - licenseAuth: []
1906
+ parameters:
1907
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
1908
+ requestBody:
1909
+ required: true
1910
+ content:
1911
+ application/json:
1912
+ schema:
1913
+ $ref: "#/components/schemas/ConsumeLicenseRequest"
1914
+ responses:
1915
+ "200":
1916
+ description: Signed entitlement response with updated balances.
1917
+ content:
1918
+ application/json:
1919
+ schema:
1920
+ $ref: "#/components/schemas/SignedRuntimeEntitlementEnvelope"
1921
+ "400":
1922
+ $ref: "#/components/responses/BadRequest"
1923
+ "401":
1924
+ $ref: "#/components/responses/UnauthorizedLicense"
1925
+ "403":
1926
+ $ref: "#/components/responses/ForbiddenRuntime"
1927
+ "404":
1928
+ $ref: "#/components/responses/NotFound"
1929
+ "409":
1930
+ $ref: "#/components/responses/Conflict"
1931
+ "422":
1932
+ $ref: "#/components/responses/ValidationError"
1933
+ /api/v1/license/offline:
1934
+ post:
1935
+ operationId: issueOfflineLicense
1936
+ tags: [runtime]
1937
+ summary: Issue an encrypted offline license envelope for a bound device
1938
+ description: |
1939
+ The returned payload is encrypted with a key derived from the license key and
1940
+ contains a signed inner payload. Verify the inner signature after decryption
1941
+ against `/api/v1/system/public-keys`.
1942
+ security:
1943
+ - licenseAuth: []
1944
+ requestBody:
1945
+ required: true
1946
+ content:
1947
+ application/json:
1948
+ schema:
1949
+ $ref: "#/components/schemas/RuntimeBindingRequest"
1950
+ responses:
1951
+ "200":
1952
+ description: Encrypted offline license envelope.
1953
+ content:
1954
+ application/json:
1955
+ schema:
1956
+ type: object
1957
+ required:
1958
+ - data
1959
+ - meta
1960
+ properties:
1961
+ data:
1962
+ $ref: "#/components/schemas/OfflineEnvelope"
1963
+ meta:
1964
+ $ref: "#/components/schemas/ResponseMeta"
1965
+ "400":
1966
+ $ref: "#/components/responses/InvalidJSON"
1967
+ "401":
1968
+ $ref: "#/components/responses/UnauthorizedLicense"
1969
+ "403":
1970
+ $ref: "#/components/responses/ForbiddenRuntime"
1971
+ "404":
1972
+ $ref: "#/components/responses/NotFound"
1973
+ "422":
1974
+ $ref: "#/components/responses/ValidationError"
1975
+ /api/v1/license/deactivate:
1976
+ post:
1977
+ operationId: deactivateLicense
1978
+ tags: [runtime]
1979
+ summary: Deactivate a bound license device
1980
+ security:
1981
+ - licenseAuth: []
1982
+ parameters:
1983
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
1984
+ requestBody:
1985
+ required: true
1986
+ content:
1987
+ application/json:
1988
+ schema:
1989
+ $ref: "#/components/schemas/RuntimeBindingRequest"
1990
+ responses:
1991
+ "200":
1992
+ description: Signed deactivation response.
1993
+ content:
1994
+ application/json:
1995
+ schema:
1996
+ $ref: "#/components/schemas/SignedRuntimeDeactivationEnvelope"
1997
+ "400":
1998
+ $ref: "#/components/responses/BadRequest"
1999
+ "401":
2000
+ $ref: "#/components/responses/UnauthorizedLicense"
2001
+ "403":
2002
+ $ref: "#/components/responses/ForbiddenRuntime"
2003
+ "404":
2004
+ $ref: "#/components/responses/NotFound"
2005
+ "409":
2006
+ $ref: "#/components/responses/Conflict"
2007
+ "422":
2008
+ $ref: "#/components/responses/ValidationError"
2009
+ /api/v1/license/floating/checkout:
2010
+ post:
2011
+ operationId: checkoutFloatingLicense
2012
+ tags: [runtime]
2013
+ summary: Check out a floating lease for a hardware or container binding
2014
+ security:
2015
+ - licenseAuth: []
2016
+ parameters:
2017
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
2018
+ requestBody:
2019
+ required: true
2020
+ content:
2021
+ application/json:
2022
+ schema:
2023
+ $ref: "#/components/schemas/RuntimeBindingRequest"
2024
+ responses:
2025
+ "200":
2026
+ description: Signed floating checkout response.
2027
+ content:
2028
+ application/json:
2029
+ schema:
2030
+ $ref: "#/components/schemas/SignedRuntimeFloatingCheckoutEnvelope"
2031
+ "400":
2032
+ $ref: "#/components/responses/BadRequest"
2033
+ "401":
2034
+ $ref: "#/components/responses/UnauthorizedLicense"
2035
+ "403":
2036
+ $ref: "#/components/responses/ForbiddenRuntime"
2037
+ "409":
2038
+ $ref: "#/components/responses/Conflict"
2039
+ "422":
2040
+ $ref: "#/components/responses/ValidationError"
2041
+ /api/v1/license/floating/checkin:
2042
+ post:
2043
+ operationId: checkinFloatingLicense
2044
+ tags: [runtime]
2045
+ summary: Check in a floating lease token
2046
+ security:
2047
+ - licenseAuth: []
2048
+ parameters:
2049
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
2050
+ requestBody:
2051
+ required: true
2052
+ content:
2053
+ application/json:
2054
+ schema:
2055
+ $ref: "#/components/schemas/FloatingLeaseRequest"
2056
+ responses:
2057
+ "200":
2058
+ description: Signed floating checkin response.
2059
+ content:
2060
+ application/json:
2061
+ schema:
2062
+ $ref: "#/components/schemas/SignedRuntimeFloatingLeaseEnvelope"
2063
+ "400":
2064
+ $ref: "#/components/responses/BadRequest"
2065
+ "401":
2066
+ $ref: "#/components/responses/UnauthorizedLicense"
2067
+ "404":
2068
+ $ref: "#/components/responses/NotFound"
2069
+ "409":
2070
+ $ref: "#/components/responses/Conflict"
2071
+ "422":
2072
+ $ref: "#/components/responses/ValidationError"
2073
+ /api/v1/license/floating/heartbeat:
2074
+ post:
2075
+ operationId: heartbeatFloatingLicense
2076
+ tags: [runtime]
2077
+ summary: Extend a floating lease before it expires
2078
+ security:
2079
+ - licenseAuth: []
2080
+ requestBody:
2081
+ required: true
2082
+ content:
2083
+ application/json:
2084
+ schema:
2085
+ $ref: "#/components/schemas/FloatingLeaseRequest"
2086
+ responses:
2087
+ "200":
2088
+ description: Signed floating heartbeat response.
2089
+ content:
2090
+ application/json:
2091
+ schema:
2092
+ $ref: "#/components/schemas/SignedRuntimeFloatingLeaseEnvelope"
2093
+ "400":
2094
+ $ref: "#/components/responses/InvalidJSON"
2095
+ "401":
2096
+ $ref: "#/components/responses/UnauthorizedLicense"
2097
+ "403":
2098
+ $ref: "#/components/responses/ForbiddenRuntime"
2099
+ "404":
2100
+ $ref: "#/components/responses/NotFound"
2101
+ "422":
2102
+ $ref: "#/components/responses/ValidationError"
2103
+ /api/v1/products:
2104
+ get:
2105
+ operationId: listProducts
2106
+ tags: [products]
2107
+ summary: List products
2108
+ x-required-scopes: ["product:read"]
2109
+ security:
2110
+ - bearerAuth: []
2111
+ parameters:
2112
+ - $ref: "#/components/parameters/LimitParam"
2113
+ responses:
2114
+ "200":
2115
+ description: Product list.
2116
+ content:
2117
+ application/json:
2118
+ schema:
2119
+ type: object
2120
+ required:
2121
+ - data
2122
+ - meta
2123
+ properties:
2124
+ data:
2125
+ type: array
2126
+ items:
2127
+ $ref: "#/components/schemas/Product"
2128
+ meta:
2129
+ $ref: "#/components/schemas/ResponseMeta"
2130
+ "401":
2131
+ $ref: "#/components/responses/UnauthorizedManagement"
2132
+ "403":
2133
+ $ref: "#/components/responses/ForbiddenScope"
2134
+ post:
2135
+ operationId: createProduct
2136
+ tags: [products]
2137
+ summary: Create a product
2138
+ x-required-scopes: ["product:write"]
2139
+ security:
2140
+ - bearerAuth: []
2141
+ requestBody:
2142
+ required: true
2143
+ content:
2144
+ application/json:
2145
+ schema:
2146
+ $ref: "#/components/schemas/ProductCreateRequest"
2147
+ responses:
2148
+ "201":
2149
+ description: Product created.
2150
+ content:
2151
+ application/json:
2152
+ schema:
2153
+ type: object
2154
+ required:
2155
+ - data
2156
+ - meta
2157
+ properties:
2158
+ data:
2159
+ $ref: "#/components/schemas/Product"
2160
+ meta:
2161
+ $ref: "#/components/schemas/ResponseMeta"
2162
+ "400":
2163
+ $ref: "#/components/responses/InvalidJSON"
2164
+ "401":
2165
+ $ref: "#/components/responses/UnauthorizedManagement"
2166
+ "403":
2167
+ $ref: "#/components/responses/ForbiddenScope"
2168
+ "409":
2169
+ $ref: "#/components/responses/Conflict"
2170
+ "422":
2171
+ $ref: "#/components/responses/ValidationError"
2172
+ /api/v1/products/{id}:
2173
+ get:
2174
+ operationId: getProduct
2175
+ tags: [products]
2176
+ summary: Get a product
2177
+ x-required-scopes: ["product:read"]
2178
+ security:
2179
+ - bearerAuth: []
2180
+ parameters:
2181
+ - $ref: "#/components/parameters/IDPath"
2182
+ responses:
2183
+ "200":
2184
+ description: Product record.
2185
+ content:
2186
+ application/json:
2187
+ schema:
2188
+ type: object
2189
+ required:
2190
+ - data
2191
+ - meta
2192
+ properties:
2193
+ data:
2194
+ $ref: "#/components/schemas/Product"
2195
+ meta:
2196
+ $ref: "#/components/schemas/ResponseMeta"
2197
+ "401":
2198
+ $ref: "#/components/responses/UnauthorizedManagement"
2199
+ "403":
2200
+ $ref: "#/components/responses/ForbiddenScope"
2201
+ "404":
2202
+ $ref: "#/components/responses/NotFound"
2203
+ patch:
2204
+ operationId: updateProduct
2205
+ tags: [products]
2206
+ summary: Update a product
2207
+ x-required-scopes: ["product:write"]
2208
+ security:
2209
+ - bearerAuth: []
2210
+ parameters:
2211
+ - $ref: "#/components/parameters/IDPath"
2212
+ requestBody:
2213
+ required: true
2214
+ content:
2215
+ application/json:
2216
+ schema:
2217
+ $ref: "#/components/schemas/ProductUpdateRequest"
2218
+ responses:
2219
+ "200":
2220
+ description: Product updated.
2221
+ content:
2222
+ application/json:
2223
+ schema:
2224
+ type: object
2225
+ required:
2226
+ - data
2227
+ - meta
2228
+ properties:
2229
+ data:
2230
+ $ref: "#/components/schemas/Product"
2231
+ meta:
2232
+ $ref: "#/components/schemas/ResponseMeta"
2233
+ "400":
2234
+ $ref: "#/components/responses/InvalidJSON"
2235
+ "401":
2236
+ $ref: "#/components/responses/UnauthorizedManagement"
2237
+ "403":
2238
+ $ref: "#/components/responses/ForbiddenScope"
2239
+ "404":
2240
+ $ref: "#/components/responses/NotFound"
2241
+ "409":
2242
+ $ref: "#/components/responses/Conflict"
2243
+ "422":
2244
+ $ref: "#/components/responses/ValidationError"
2245
+ delete:
2246
+ operationId: deleteProduct
2247
+ tags: [products]
2248
+ summary: Delete a product
2249
+ x-required-scopes: ["product:write"]
2250
+ security:
2251
+ - bearerAuth: []
2252
+ parameters:
2253
+ - $ref: "#/components/parameters/IDPath"
2254
+ responses:
2255
+ "204":
2256
+ description: Product deleted.
2257
+ "401":
2258
+ $ref: "#/components/responses/UnauthorizedManagement"
2259
+ "403":
2260
+ $ref: "#/components/responses/ForbiddenScope"
2261
+ "404":
2262
+ $ref: "#/components/responses/NotFound"
2263
+ "409":
2264
+ $ref: "#/components/responses/Conflict"
2265
+ /api/v1/products/{id}/versions:
2266
+ get:
2267
+ operationId: listProductVersions
2268
+ tags: [versions]
2269
+ summary: List product versions
2270
+ x-required-scopes: ["product:read"]
2271
+ security:
2272
+ - bearerAuth: []
2273
+ parameters:
2274
+ - $ref: "#/components/parameters/IDPath"
2275
+ - $ref: "#/components/parameters/LimitParam"
2276
+ responses:
2277
+ "200":
2278
+ description: Product version list.
2279
+ content:
2280
+ application/json:
2281
+ schema:
2282
+ type: object
2283
+ required:
2284
+ - data
2285
+ - meta
2286
+ properties:
2287
+ data:
2288
+ type: array
2289
+ items:
2290
+ $ref: "#/components/schemas/ProductVersion"
2291
+ meta:
2292
+ $ref: "#/components/schemas/ResponseMeta"
2293
+ "401":
2294
+ $ref: "#/components/responses/UnauthorizedManagement"
2295
+ "403":
2296
+ $ref: "#/components/responses/ForbiddenScope"
2297
+ post:
2298
+ operationId: createProductVersion
2299
+ tags: [versions]
2300
+ summary: Create a product version
2301
+ x-required-scopes: ["product:write"]
2302
+ security:
2303
+ - bearerAuth: []
2304
+ parameters:
2305
+ - $ref: "#/components/parameters/IDPath"
2306
+ requestBody:
2307
+ required: true
2308
+ content:
2309
+ application/json:
2310
+ schema:
2311
+ $ref: "#/components/schemas/ProductVersionCreateRequest"
2312
+ responses:
2313
+ "201":
2314
+ description: Product version created.
2315
+ content:
2316
+ application/json:
2317
+ schema:
2318
+ type: object
2319
+ required:
2320
+ - data
2321
+ - meta
2322
+ properties:
2323
+ data:
2324
+ $ref: "#/components/schemas/ProductVersion"
2325
+ meta:
2326
+ $ref: "#/components/schemas/ResponseMeta"
2327
+ "400":
2328
+ $ref: "#/components/responses/InvalidJSON"
2329
+ "401":
2330
+ $ref: "#/components/responses/UnauthorizedManagement"
2331
+ "403":
2332
+ $ref: "#/components/responses/ForbiddenScope"
2333
+ "404":
2334
+ $ref: "#/components/responses/NotFound"
2335
+ "409":
2336
+ $ref: "#/components/responses/Conflict"
2337
+ "422":
2338
+ $ref: "#/components/responses/ValidationError"
2339
+ /api/v1/products/{id}/subscriptions:
2340
+ get:
2341
+ operationId: listProductSubscriptions
2342
+ tags: [commerce]
2343
+ summary: List subscriptions for a product
2344
+ x-required-scopes: ["product:read"]
2345
+ security:
2346
+ - bearerAuth: []
2347
+ parameters:
2348
+ - $ref: "#/components/parameters/IDPath"
2349
+ - $ref: "#/components/parameters/LimitParam"
2350
+ responses:
2351
+ "200":
2352
+ description: Subscription list.
2353
+ content:
2354
+ application/json:
2355
+ schema:
2356
+ type: object
2357
+ required:
2358
+ - data
2359
+ - meta
2360
+ properties:
2361
+ data:
2362
+ type: array
2363
+ items:
2364
+ $ref: "#/components/schemas/Subscription"
2365
+ meta:
2366
+ $ref: "#/components/schemas/ResponseMeta"
2367
+ "401":
2368
+ $ref: "#/components/responses/UnauthorizedManagement"
2369
+ "403":
2370
+ $ref: "#/components/responses/ForbiddenScope"
2371
+ post:
2372
+ operationId: createSubscription
2373
+ tags: [commerce]
2374
+ summary: Create a subscription record for a product
2375
+ x-required-scopes: ["product:write"]
2376
+ security:
2377
+ - bearerAuth: []
2378
+ parameters:
2379
+ - $ref: "#/components/parameters/IDPath"
2380
+ requestBody:
2381
+ required: true
2382
+ content:
2383
+ application/json:
2384
+ schema:
2385
+ $ref: "#/components/schemas/SubscriptionCreateRequest"
2386
+ responses:
2387
+ "201":
2388
+ description: Subscription created.
2389
+ content:
2390
+ application/json:
2391
+ schema:
2392
+ type: object
2393
+ required:
2394
+ - data
2395
+ - meta
2396
+ properties:
2397
+ data:
2398
+ $ref: "#/components/schemas/Subscription"
2399
+ meta:
2400
+ $ref: "#/components/schemas/ResponseMeta"
2401
+ "400":
2402
+ $ref: "#/components/responses/InvalidJSON"
2403
+ "401":
2404
+ $ref: "#/components/responses/UnauthorizedManagement"
2405
+ "403":
2406
+ $ref: "#/components/responses/ForbiddenScope"
2407
+ "404":
2408
+ $ref: "#/components/responses/NotFound"
2409
+ "409":
2410
+ $ref: "#/components/responses/Conflict"
2411
+ "422":
2412
+ $ref: "#/components/responses/ValidationError"
2413
+ /api/v1/subscriptions/{id}:
2414
+ get:
2415
+ operationId: getSubscription
2416
+ tags: [commerce]
2417
+ summary: Get a subscription record
2418
+ x-required-scopes: ["product:read"]
2419
+ security:
2420
+ - bearerAuth: []
2421
+ parameters:
2422
+ - $ref: "#/components/parameters/IDPath"
2423
+ responses:
2424
+ "200":
2425
+ description: Subscription record.
2426
+ content:
2427
+ application/json:
2428
+ schema:
2429
+ type: object
2430
+ required:
2431
+ - data
2432
+ - meta
2433
+ properties:
2434
+ data:
2435
+ $ref: "#/components/schemas/Subscription"
2436
+ meta:
2437
+ $ref: "#/components/schemas/ResponseMeta"
2438
+ "401":
2439
+ $ref: "#/components/responses/UnauthorizedManagement"
2440
+ "403":
2441
+ $ref: "#/components/responses/ForbiddenScope"
2442
+ "404":
2443
+ $ref: "#/components/responses/NotFound"
2444
+ patch:
2445
+ operationId: updateSubscription
2446
+ tags: [commerce]
2447
+ summary: Update a subscription record
2448
+ x-required-scopes: ["product:write"]
2449
+ security:
2450
+ - bearerAuth: []
2451
+ parameters:
2452
+ - $ref: "#/components/parameters/IDPath"
2453
+ requestBody:
2454
+ required: true
2455
+ content:
2456
+ application/json:
2457
+ schema:
2458
+ $ref: "#/components/schemas/SubscriptionUpdateRequest"
2459
+ responses:
2460
+ "200":
2461
+ description: Subscription updated.
2462
+ content:
2463
+ application/json:
2464
+ schema:
2465
+ type: object
2466
+ required:
2467
+ - data
2468
+ - meta
2469
+ properties:
2470
+ data:
2471
+ $ref: "#/components/schemas/Subscription"
2472
+ meta:
2473
+ $ref: "#/components/schemas/ResponseMeta"
2474
+ "400":
2475
+ $ref: "#/components/responses/InvalidJSON"
2476
+ "401":
2477
+ $ref: "#/components/responses/UnauthorizedManagement"
2478
+ "403":
2479
+ $ref: "#/components/responses/ForbiddenScope"
2480
+ "404":
2481
+ $ref: "#/components/responses/NotFound"
2482
+ "409":
2483
+ $ref: "#/components/responses/Conflict"
2484
+ "422":
2485
+ $ref: "#/components/responses/ValidationError"
2486
+ /api/v1/products/{id}/orders:
2487
+ get:
2488
+ operationId: listProductOrders
2489
+ tags: [commerce]
2490
+ summary: List orders for a product
2491
+ x-required-scopes: ["product:read"]
2492
+ security:
2493
+ - bearerAuth: []
2494
+ parameters:
2495
+ - $ref: "#/components/parameters/IDPath"
2496
+ - $ref: "#/components/parameters/LimitParam"
2497
+ responses:
2498
+ "200":
2499
+ description: Order list.
2500
+ content:
2501
+ application/json:
2502
+ schema:
2503
+ type: object
2504
+ required:
2505
+ - data
2506
+ - meta
2507
+ properties:
2508
+ data:
2509
+ type: array
2510
+ items:
2511
+ $ref: "#/components/schemas/Order"
2512
+ meta:
2513
+ $ref: "#/components/schemas/ResponseMeta"
2514
+ "401":
2515
+ $ref: "#/components/responses/UnauthorizedManagement"
2516
+ "403":
2517
+ $ref: "#/components/responses/ForbiddenScope"
2518
+ post:
2519
+ operationId: createOrder
2520
+ tags: [commerce]
2521
+ summary: Create an order record for a product
2522
+ x-required-scopes: ["product:write"]
2523
+ security:
2524
+ - bearerAuth: []
2525
+ parameters:
2526
+ - $ref: "#/components/parameters/IDPath"
2527
+ requestBody:
2528
+ required: true
2529
+ content:
2530
+ application/json:
2531
+ schema:
2532
+ $ref: "#/components/schemas/OrderCreateRequest"
2533
+ responses:
2534
+ "201":
2535
+ description: Order created.
2536
+ content:
2537
+ application/json:
2538
+ schema:
2539
+ type: object
2540
+ required:
2541
+ - data
2542
+ - meta
2543
+ properties:
2544
+ data:
2545
+ $ref: "#/components/schemas/Order"
2546
+ meta:
2547
+ $ref: "#/components/schemas/ResponseMeta"
2548
+ "400":
2549
+ $ref: "#/components/responses/InvalidJSON"
2550
+ "401":
2551
+ $ref: "#/components/responses/UnauthorizedManagement"
2552
+ "403":
2553
+ $ref: "#/components/responses/ForbiddenScope"
2554
+ "404":
2555
+ $ref: "#/components/responses/NotFound"
2556
+ "409":
2557
+ $ref: "#/components/responses/Conflict"
2558
+ "422":
2559
+ $ref: "#/components/responses/ValidationError"
2560
+ /api/v1/orders/{id}:
2561
+ get:
2562
+ operationId: getOrder
2563
+ tags: [commerce]
2564
+ summary: Get an order record
2565
+ x-required-scopes: ["product:read"]
2566
+ security:
2567
+ - bearerAuth: []
2568
+ parameters:
2569
+ - $ref: "#/components/parameters/IDPath"
2570
+ responses:
2571
+ "200":
2572
+ description: Order record.
2573
+ content:
2574
+ application/json:
2575
+ schema:
2576
+ type: object
2577
+ required:
2578
+ - data
2579
+ - meta
2580
+ properties:
2581
+ data:
2582
+ $ref: "#/components/schemas/Order"
2583
+ meta:
2584
+ $ref: "#/components/schemas/ResponseMeta"
2585
+ "401":
2586
+ $ref: "#/components/responses/UnauthorizedManagement"
2587
+ "403":
2588
+ $ref: "#/components/responses/ForbiddenScope"
2589
+ "404":
2590
+ $ref: "#/components/responses/NotFound"
2591
+ patch:
2592
+ operationId: updateOrder
2593
+ tags: [commerce]
2594
+ summary: Update an order record
2595
+ x-required-scopes: ["product:write"]
2596
+ security:
2597
+ - bearerAuth: []
2598
+ parameters:
2599
+ - $ref: "#/components/parameters/IDPath"
2600
+ requestBody:
2601
+ required: true
2602
+ content:
2603
+ application/json:
2604
+ schema:
2605
+ $ref: "#/components/schemas/OrderUpdateRequest"
2606
+ responses:
2607
+ "200":
2608
+ description: Order updated.
2609
+ content:
2610
+ application/json:
2611
+ schema:
2612
+ type: object
2613
+ required:
2614
+ - data
2615
+ - meta
2616
+ properties:
2617
+ data:
2618
+ $ref: "#/components/schemas/Order"
2619
+ meta:
2620
+ $ref: "#/components/schemas/ResponseMeta"
2621
+ "400":
2622
+ $ref: "#/components/responses/InvalidJSON"
2623
+ "401":
2624
+ $ref: "#/components/responses/UnauthorizedManagement"
2625
+ "403":
2626
+ $ref: "#/components/responses/ForbiddenScope"
2627
+ "404":
2628
+ $ref: "#/components/responses/NotFound"
2629
+ "409":
2630
+ $ref: "#/components/responses/Conflict"
2631
+ "422":
2632
+ $ref: "#/components/responses/ValidationError"
2633
+ /api/v1/products/{id}/custom-fields:
2634
+ get:
2635
+ operationId: listProductCustomFieldDefinitions
2636
+ tags: [custom-fields]
2637
+ summary: List product custom field definitions
2638
+ x-required-scopes: ["product:read"]
2639
+ security:
2640
+ - bearerAuth: []
2641
+ parameters:
2642
+ - $ref: "#/components/parameters/IDPath"
2643
+ - $ref: "#/components/parameters/LimitParam"
2644
+ responses:
2645
+ "200":
2646
+ description: Custom field definition list.
2647
+ content:
2648
+ application/json:
2649
+ schema:
2650
+ type: object
2651
+ required:
2652
+ - data
2653
+ - meta
2654
+ properties:
2655
+ data:
2656
+ type: array
2657
+ items:
2658
+ $ref: "#/components/schemas/CustomFieldDefinition"
2659
+ meta:
2660
+ $ref: "#/components/schemas/ResponseMeta"
2661
+ "401":
2662
+ $ref: "#/components/responses/UnauthorizedManagement"
2663
+ "403":
2664
+ $ref: "#/components/responses/ForbiddenScope"
2665
+ post:
2666
+ operationId: createProductCustomFieldDefinition
2667
+ tags: [custom-fields]
2668
+ summary: Create a product custom field definition
2669
+ x-required-scopes: ["product:write"]
2670
+ security:
2671
+ - bearerAuth: []
2672
+ parameters:
2673
+ - $ref: "#/components/parameters/IDPath"
2674
+ requestBody:
2675
+ required: true
2676
+ content:
2677
+ application/json:
2678
+ schema:
2679
+ $ref: "#/components/schemas/CustomFieldDefinitionCreateRequest"
2680
+ responses:
2681
+ "201":
2682
+ description: Custom field definition created.
2683
+ content:
2684
+ application/json:
2685
+ schema:
2686
+ type: object
2687
+ required:
2688
+ - data
2689
+ - meta
2690
+ properties:
2691
+ data:
2692
+ $ref: "#/components/schemas/CustomFieldDefinition"
2693
+ meta:
2694
+ $ref: "#/components/schemas/ResponseMeta"
2695
+ "400":
2696
+ $ref: "#/components/responses/InvalidJSON"
2697
+ "401":
2698
+ $ref: "#/components/responses/UnauthorizedManagement"
2699
+ "403":
2700
+ $ref: "#/components/responses/ForbiddenScope"
2701
+ "404":
2702
+ $ref: "#/components/responses/NotFound"
2703
+ "409":
2704
+ $ref: "#/components/responses/Conflict"
2705
+ "422":
2706
+ $ref: "#/components/responses/ValidationError"
2707
+ /api/v1/products/{id}/custom-fields/{field_id}:
2708
+ get:
2709
+ operationId: getProductCustomFieldDefinition
2710
+ tags: [custom-fields]
2711
+ summary: Get a product custom field definition
2712
+ x-required-scopes: ["product:read"]
2713
+ security:
2714
+ - bearerAuth: []
2715
+ parameters:
2716
+ - $ref: "#/components/parameters/IDPath"
2717
+ - $ref: "#/components/parameters/FieldIDPath"
2718
+ responses:
2719
+ "200":
2720
+ description: Custom field definition.
2721
+ content:
2722
+ application/json:
2723
+ schema:
2724
+ type: object
2725
+ required:
2726
+ - data
2727
+ - meta
2728
+ properties:
2729
+ data:
2730
+ $ref: "#/components/schemas/CustomFieldDefinition"
2731
+ meta:
2732
+ $ref: "#/components/schemas/ResponseMeta"
2733
+ "401":
2734
+ $ref: "#/components/responses/UnauthorizedManagement"
2735
+ "403":
2736
+ $ref: "#/components/responses/ForbiddenScope"
2737
+ "404":
2738
+ $ref: "#/components/responses/NotFound"
2739
+ patch:
2740
+ operationId: updateProductCustomFieldDefinition
2741
+ tags: [custom-fields]
2742
+ summary: Update a product custom field definition
2743
+ x-required-scopes: ["product:write"]
2744
+ security:
2745
+ - bearerAuth: []
2746
+ parameters:
2747
+ - $ref: "#/components/parameters/IDPath"
2748
+ - $ref: "#/components/parameters/FieldIDPath"
2749
+ requestBody:
2750
+ required: true
2751
+ content:
2752
+ application/json:
2753
+ schema:
2754
+ $ref: "#/components/schemas/CustomFieldDefinitionUpdateRequest"
2755
+ responses:
2756
+ "200":
2757
+ description: Custom field definition updated.
2758
+ content:
2759
+ application/json:
2760
+ schema:
2761
+ type: object
2762
+ required:
2763
+ - data
2764
+ - meta
2765
+ properties:
2766
+ data:
2767
+ $ref: "#/components/schemas/CustomFieldDefinition"
2768
+ meta:
2769
+ $ref: "#/components/schemas/ResponseMeta"
2770
+ "400":
2771
+ $ref: "#/components/responses/InvalidJSON"
2772
+ "401":
2773
+ $ref: "#/components/responses/UnauthorizedManagement"
2774
+ "403":
2775
+ $ref: "#/components/responses/ForbiddenScope"
2776
+ "404":
2777
+ $ref: "#/components/responses/NotFound"
2778
+ "409":
2779
+ $ref: "#/components/responses/Conflict"
2780
+ "422":
2781
+ $ref: "#/components/responses/ValidationError"
2782
+ delete:
2783
+ operationId: deleteProductCustomFieldDefinition
2784
+ tags: [custom-fields]
2785
+ summary: Delete a product custom field definition
2786
+ x-required-scopes: ["product:write"]
2787
+ security:
2788
+ - bearerAuth: []
2789
+ parameters:
2790
+ - $ref: "#/components/parameters/IDPath"
2791
+ - $ref: "#/components/parameters/FieldIDPath"
2792
+ responses:
2793
+ "204":
2794
+ description: Custom field definition deleted.
2795
+ "401":
2796
+ $ref: "#/components/responses/UnauthorizedManagement"
2797
+ "403":
2798
+ $ref: "#/components/responses/ForbiddenScope"
2799
+ "404":
2800
+ $ref: "#/components/responses/NotFound"
2801
+ "409":
2802
+ $ref: "#/components/responses/Conflict"
2803
+ /api/v1/products/{id}/policies:
2804
+ get:
2805
+ operationId: listPoliciesByProduct
2806
+ tags: [policies]
2807
+ summary: List policies for a product
2808
+ x-required-scopes: ["product:read"]
2809
+ security:
2810
+ - bearerAuth: []
2811
+ parameters:
2812
+ - $ref: "#/components/parameters/IDPath"
2813
+ - $ref: "#/components/parameters/LimitParam"
2814
+ responses:
2815
+ "200":
2816
+ description: Policy list.
2817
+ content:
2818
+ application/json:
2819
+ schema:
2820
+ type: object
2821
+ required:
2822
+ - data
2823
+ - meta
2824
+ properties:
2825
+ data:
2826
+ type: array
2827
+ items:
2828
+ $ref: "#/components/schemas/Policy"
2829
+ meta:
2830
+ $ref: "#/components/schemas/ResponseMeta"
2831
+ "401":
2832
+ $ref: "#/components/responses/UnauthorizedManagement"
2833
+ "403":
2834
+ $ref: "#/components/responses/ForbiddenScope"
2835
+ post:
2836
+ operationId: createPolicy
2837
+ tags: [policies]
2838
+ summary: Create a policy for a product
2839
+ x-required-scopes: ["product:write"]
2840
+ security:
2841
+ - bearerAuth: []
2842
+ parameters:
2843
+ - $ref: "#/components/parameters/IDPath"
2844
+ requestBody:
2845
+ required: true
2846
+ content:
2847
+ application/json:
2848
+ schema:
2849
+ $ref: "#/components/schemas/PolicyCreateRequest"
2850
+ responses:
2851
+ "201":
2852
+ description: Policy created.
2853
+ content:
2854
+ application/json:
2855
+ schema:
2856
+ type: object
2857
+ required:
2858
+ - data
2859
+ - meta
2860
+ properties:
2861
+ data:
2862
+ $ref: "#/components/schemas/Policy"
2863
+ meta:
2864
+ $ref: "#/components/schemas/ResponseMeta"
2865
+ "400":
2866
+ $ref: "#/components/responses/InvalidJSON"
2867
+ "401":
2868
+ $ref: "#/components/responses/UnauthorizedManagement"
2869
+ "403":
2870
+ $ref: "#/components/responses/ForbiddenScope"
2871
+ "404":
2872
+ $ref: "#/components/responses/NotFound"
2873
+ "409":
2874
+ $ref: "#/components/responses/Conflict"
2875
+ "422":
2876
+ $ref: "#/components/responses/ValidationError"
2877
+ /api/v1/products/{id}/features:
2878
+ get:
2879
+ operationId: listFeaturesByProduct
2880
+ tags: [features]
2881
+ summary: List features for a product
2882
+ x-required-scopes: ["product:read"]
2883
+ security:
2884
+ - bearerAuth: []
2885
+ parameters:
2886
+ - $ref: "#/components/parameters/IDPath"
2887
+ - $ref: "#/components/parameters/LimitParam"
2888
+ responses:
2889
+ "200":
2890
+ description: Feature list.
2891
+ content:
2892
+ application/json:
2893
+ schema:
2894
+ type: object
2895
+ required:
2896
+ - data
2897
+ - meta
2898
+ properties:
2899
+ data:
2900
+ type: array
2901
+ items:
2902
+ $ref: "#/components/schemas/Feature"
2903
+ meta:
2904
+ $ref: "#/components/schemas/ResponseMeta"
2905
+ "401":
2906
+ $ref: "#/components/responses/UnauthorizedManagement"
2907
+ "403":
2908
+ $ref: "#/components/responses/ForbiddenScope"
2909
+ post:
2910
+ operationId: createFeature
2911
+ tags: [features]
2912
+ summary: Create a feature for a product
2913
+ x-required-scopes: ["product:write"]
2914
+ security:
2915
+ - bearerAuth: []
2916
+ parameters:
2917
+ - $ref: "#/components/parameters/IDPath"
2918
+ requestBody:
2919
+ required: true
2920
+ content:
2921
+ application/json:
2922
+ schema:
2923
+ $ref: "#/components/schemas/FeatureCreateRequest"
2924
+ responses:
2925
+ "201":
2926
+ description: Feature created.
2927
+ content:
2928
+ application/json:
2929
+ schema:
2930
+ type: object
2931
+ required:
2932
+ - data
2933
+ - meta
2934
+ properties:
2935
+ data:
2936
+ $ref: "#/components/schemas/Feature"
2937
+ meta:
2938
+ $ref: "#/components/schemas/ResponseMeta"
2939
+ "400":
2940
+ $ref: "#/components/responses/InvalidJSON"
2941
+ "401":
2942
+ $ref: "#/components/responses/UnauthorizedManagement"
2943
+ "403":
2944
+ $ref: "#/components/responses/ForbiddenScope"
2945
+ "404":
2946
+ $ref: "#/components/responses/NotFound"
2947
+ "409":
2948
+ $ref: "#/components/responses/Conflict"
2949
+ "422":
2950
+ $ref: "#/components/responses/ValidationError"
2951
+ /api/v1/policies/{id}:
2952
+ get:
2953
+ operationId: getPolicy
2954
+ tags: [policies]
2955
+ summary: Get a policy
2956
+ x-required-scopes: ["product:read"]
2957
+ security:
2958
+ - bearerAuth: []
2959
+ parameters:
2960
+ - $ref: "#/components/parameters/IDPath"
2961
+ responses:
2962
+ "200":
2963
+ description: Policy record.
2964
+ content:
2965
+ application/json:
2966
+ schema:
2967
+ type: object
2968
+ required:
2969
+ - data
2970
+ - meta
2971
+ properties:
2972
+ data:
2973
+ $ref: "#/components/schemas/Policy"
2974
+ meta:
2975
+ $ref: "#/components/schemas/ResponseMeta"
2976
+ "401":
2977
+ $ref: "#/components/responses/UnauthorizedManagement"
2978
+ "403":
2979
+ $ref: "#/components/responses/ForbiddenScope"
2980
+ "404":
2981
+ $ref: "#/components/responses/NotFound"
2982
+ patch:
2983
+ operationId: updatePolicy
2984
+ tags: [policies]
2985
+ summary: Update a policy
2986
+ x-required-scopes: ["product:write"]
2987
+ security:
2988
+ - bearerAuth: []
2989
+ parameters:
2990
+ - $ref: "#/components/parameters/IDPath"
2991
+ requestBody:
2992
+ required: true
2993
+ content:
2994
+ application/json:
2995
+ schema:
2996
+ $ref: "#/components/schemas/PolicyUpdateRequest"
2997
+ responses:
2998
+ "200":
2999
+ description: Policy updated.
3000
+ content:
3001
+ application/json:
3002
+ schema:
3003
+ type: object
3004
+ required:
3005
+ - data
3006
+ - meta
3007
+ properties:
3008
+ data:
3009
+ $ref: "#/components/schemas/Policy"
3010
+ meta:
3011
+ $ref: "#/components/schemas/ResponseMeta"
3012
+ "400":
3013
+ $ref: "#/components/responses/InvalidJSON"
3014
+ "401":
3015
+ $ref: "#/components/responses/UnauthorizedManagement"
3016
+ "403":
3017
+ $ref: "#/components/responses/ForbiddenScope"
3018
+ "404":
3019
+ $ref: "#/components/responses/NotFound"
3020
+ "409":
3021
+ $ref: "#/components/responses/Conflict"
3022
+ "422":
3023
+ $ref: "#/components/responses/ValidationError"
3024
+ delete:
3025
+ operationId: deletePolicy
3026
+ tags: [policies]
3027
+ summary: Delete a policy
3028
+ x-required-scopes: ["product:write"]
3029
+ security:
3030
+ - bearerAuth: []
3031
+ parameters:
3032
+ - $ref: "#/components/parameters/IDPath"
3033
+ responses:
3034
+ "204":
3035
+ description: Policy deleted.
3036
+ "401":
3037
+ $ref: "#/components/responses/UnauthorizedManagement"
3038
+ "403":
3039
+ $ref: "#/components/responses/ForbiddenScope"
3040
+ "404":
3041
+ $ref: "#/components/responses/NotFound"
3042
+ "409":
3043
+ $ref: "#/components/responses/Conflict"
3044
+ /api/v1/features/{id}:
3045
+ get:
3046
+ operationId: getFeature
3047
+ tags: [features]
3048
+ summary: Get a feature
3049
+ x-required-scopes: ["product:read"]
3050
+ security:
3051
+ - bearerAuth: []
3052
+ parameters:
3053
+ - $ref: "#/components/parameters/IDPath"
3054
+ responses:
3055
+ "200":
3056
+ description: Feature record.
3057
+ content:
3058
+ application/json:
3059
+ schema:
3060
+ type: object
3061
+ required:
3062
+ - data
3063
+ - meta
3064
+ properties:
3065
+ data:
3066
+ $ref: "#/components/schemas/Feature"
3067
+ meta:
3068
+ $ref: "#/components/schemas/ResponseMeta"
3069
+ "401":
3070
+ $ref: "#/components/responses/UnauthorizedManagement"
3071
+ "403":
3072
+ $ref: "#/components/responses/ForbiddenScope"
3073
+ "404":
3074
+ $ref: "#/components/responses/NotFound"
3075
+ /api/v1/customers:
3076
+ get:
3077
+ operationId: listCustomers
3078
+ tags: [customers]
3079
+ summary: List customers
3080
+ x-required-scopes: ["admin"]
3081
+ security:
3082
+ - bearerAuth: []
3083
+ parameters:
3084
+ - $ref: "#/components/parameters/LimitParam"
3085
+ responses:
3086
+ "200":
3087
+ description: Customer list.
3088
+ content:
3089
+ application/json:
3090
+ schema:
3091
+ type: object
3092
+ required:
3093
+ - data
3094
+ - meta
3095
+ properties:
3096
+ data:
3097
+ type: array
3098
+ items:
3099
+ $ref: "#/components/schemas/Customer"
3100
+ meta:
3101
+ $ref: "#/components/schemas/ResponseMeta"
3102
+ "401":
3103
+ $ref: "#/components/responses/UnauthorizedManagement"
3104
+ "403":
3105
+ $ref: "#/components/responses/ForbiddenScope"
3106
+ post:
3107
+ operationId: createCustomer
3108
+ tags: [customers]
3109
+ summary: Create a customer
3110
+ x-required-scopes: ["admin"]
3111
+ security:
3112
+ - bearerAuth: []
3113
+ requestBody:
3114
+ required: true
3115
+ content:
3116
+ application/json:
3117
+ schema:
3118
+ $ref: "#/components/schemas/CustomerCreateRequest"
3119
+ responses:
3120
+ "201":
3121
+ description: Customer created.
3122
+ content:
3123
+ application/json:
3124
+ schema:
3125
+ type: object
3126
+ required:
3127
+ - data
3128
+ - meta
3129
+ properties:
3130
+ data:
3131
+ $ref: "#/components/schemas/Customer"
3132
+ meta:
3133
+ $ref: "#/components/schemas/ResponseMeta"
3134
+ "400":
3135
+ $ref: "#/components/responses/InvalidJSON"
3136
+ "401":
3137
+ $ref: "#/components/responses/UnauthorizedManagement"
3138
+ "403":
3139
+ $ref: "#/components/responses/ForbiddenScope"
3140
+ "409":
3141
+ $ref: "#/components/responses/Conflict"
3142
+ "422":
3143
+ $ref: "#/components/responses/ValidationError"
3144
+ /api/v1/customers/{id}:
3145
+ get:
3146
+ operationId: getCustomer
3147
+ tags: [customers]
3148
+ summary: Get a customer
3149
+ x-required-scopes: ["admin"]
3150
+ security:
3151
+ - bearerAuth: []
3152
+ parameters:
3153
+ - $ref: "#/components/parameters/IDPath"
3154
+ responses:
3155
+ "200":
3156
+ description: Customer record.
3157
+ content:
3158
+ application/json:
3159
+ schema:
3160
+ type: object
3161
+ required:
3162
+ - data
3163
+ - meta
3164
+ properties:
3165
+ data:
3166
+ $ref: "#/components/schemas/Customer"
3167
+ meta:
3168
+ $ref: "#/components/schemas/ResponseMeta"
3169
+ "401":
3170
+ $ref: "#/components/responses/UnauthorizedManagement"
3171
+ "403":
3172
+ $ref: "#/components/responses/ForbiddenScope"
3173
+ "404":
3174
+ $ref: "#/components/responses/NotFound"
3175
+ patch:
3176
+ operationId: updateCustomer
3177
+ tags: [customers]
3178
+ summary: Update a customer
3179
+ x-required-scopes: ["admin"]
3180
+ security:
3181
+ - bearerAuth: []
3182
+ parameters:
3183
+ - $ref: "#/components/parameters/IDPath"
3184
+ requestBody:
3185
+ required: true
3186
+ content:
3187
+ application/json:
3188
+ schema:
3189
+ $ref: "#/components/schemas/CustomerUpdateRequest"
3190
+ responses:
3191
+ "200":
3192
+ description: Customer updated.
3193
+ content:
3194
+ application/json:
3195
+ schema:
3196
+ type: object
3197
+ required:
3198
+ - data
3199
+ - meta
3200
+ properties:
3201
+ data:
3202
+ $ref: "#/components/schemas/Customer"
3203
+ meta:
3204
+ $ref: "#/components/schemas/ResponseMeta"
3205
+ "400":
3206
+ $ref: "#/components/responses/InvalidJSON"
3207
+ "401":
3208
+ $ref: "#/components/responses/UnauthorizedManagement"
3209
+ "403":
3210
+ $ref: "#/components/responses/ForbiddenScope"
3211
+ "404":
3212
+ $ref: "#/components/responses/NotFound"
3213
+ "409":
3214
+ $ref: "#/components/responses/Conflict"
3215
+ "422":
3216
+ $ref: "#/components/responses/ValidationError"
3217
+ delete:
3218
+ operationId: deleteCustomer
3219
+ tags: [customers]
3220
+ summary: Delete a customer
3221
+ x-required-scopes: ["admin"]
3222
+ security:
3223
+ - bearerAuth: []
3224
+ parameters:
3225
+ - $ref: "#/components/parameters/IDPath"
3226
+ responses:
3227
+ "204":
3228
+ description: Customer deleted.
3229
+ "401":
3230
+ $ref: "#/components/responses/UnauthorizedManagement"
3231
+ "403":
3232
+ $ref: "#/components/responses/ForbiddenScope"
3233
+ "404":
3234
+ $ref: "#/components/responses/NotFound"
3235
+ "409":
3236
+ $ref: "#/components/responses/Conflict"
3237
+ /api/v1/customers/{id}/custom-fields:
3238
+ get:
3239
+ operationId: listCustomerCustomFieldValues
3240
+ tags: [custom-fields]
3241
+ summary: List customer custom field values
3242
+ x-required-scopes: ["admin"]
3243
+ security:
3244
+ - bearerAuth: []
3245
+ parameters:
3246
+ - $ref: "#/components/parameters/IDPath"
3247
+ - $ref: "#/components/parameters/LimitParam"
3248
+ responses:
3249
+ "200":
3250
+ description: Customer custom field values.
3251
+ content:
3252
+ application/json:
3253
+ schema:
3254
+ type: object
3255
+ required:
3256
+ - data
3257
+ - meta
3258
+ properties:
3259
+ data:
3260
+ type: array
3261
+ items:
3262
+ $ref: "#/components/schemas/CustomFieldValue"
3263
+ meta:
3264
+ $ref: "#/components/schemas/ResponseMeta"
3265
+ "401":
3266
+ $ref: "#/components/responses/UnauthorizedManagement"
3267
+ "403":
3268
+ $ref: "#/components/responses/ForbiddenScope"
3269
+ "404":
3270
+ $ref: "#/components/responses/NotFound"
3271
+ /api/v1/customers/{id}/custom-fields/{field_id}:
3272
+ put:
3273
+ operationId: upsertCustomerCustomFieldValue
3274
+ tags: [custom-fields]
3275
+ summary: Upsert a customer custom field value
3276
+ x-required-scopes: ["admin"]
3277
+ security:
3278
+ - bearerAuth: []
3279
+ parameters:
3280
+ - $ref: "#/components/parameters/IDPath"
3281
+ - $ref: "#/components/parameters/FieldIDPath"
3282
+ requestBody:
3283
+ required: true
3284
+ content:
3285
+ application/json:
3286
+ schema:
3287
+ $ref: "#/components/schemas/CustomFieldValueUpsertRequest"
3288
+ responses:
3289
+ "200":
3290
+ description: Customer custom field value written.
3291
+ content:
3292
+ application/json:
3293
+ schema:
3294
+ type: object
3295
+ required:
3296
+ - data
3297
+ - meta
3298
+ properties:
3299
+ data:
3300
+ $ref: "#/components/schemas/CustomFieldValue"
3301
+ meta:
3302
+ $ref: "#/components/schemas/ResponseMeta"
3303
+ "204":
3304
+ description: Customer custom field value cleared.
3305
+ "400":
3306
+ $ref: "#/components/responses/InvalidJSON"
3307
+ "401":
3308
+ $ref: "#/components/responses/UnauthorizedManagement"
3309
+ "403":
3310
+ $ref: "#/components/responses/ForbiddenScope"
3311
+ "404":
3312
+ $ref: "#/components/responses/NotFound"
3313
+ "409":
3314
+ $ref: "#/components/responses/Conflict"
3315
+ "422":
3316
+ $ref: "#/components/responses/ValidationError"
3317
+ /api/v1/api-keys:
3318
+ get:
3319
+ operationId: listAPIKeys
3320
+ tags: [api-keys]
3321
+ summary: List management API keys
3322
+ x-required-scopes: ["admin"]
3323
+ security:
3324
+ - bearerAuth: []
3325
+ parameters:
3326
+ - $ref: "#/components/parameters/LimitParam"
3327
+ responses:
3328
+ "200":
3329
+ description: API key list.
3330
+ content:
3331
+ application/json:
3332
+ schema:
3333
+ type: object
3334
+ required:
3335
+ - data
3336
+ - meta
3337
+ properties:
3338
+ data:
3339
+ type: array
3340
+ items:
3341
+ $ref: "#/components/schemas/APIKey"
3342
+ meta:
3343
+ $ref: "#/components/schemas/ResponseMeta"
3344
+ "401":
3345
+ $ref: "#/components/responses/UnauthorizedManagement"
3346
+ "403":
3347
+ $ref: "#/components/responses/ForbiddenScope"
3348
+ post:
3349
+ operationId: createAPIKey
3350
+ tags: [api-keys]
3351
+ summary: Create a management API key
3352
+ x-required-scopes: ["admin"]
3353
+ security:
3354
+ - bearerAuth: []
3355
+ requestBody:
3356
+ required: true
3357
+ content:
3358
+ application/json:
3359
+ schema:
3360
+ $ref: "#/components/schemas/APIKeyCreateRequest"
3361
+ responses:
3362
+ "201":
3363
+ description: API key created. The raw token is returned once.
3364
+ content:
3365
+ application/json:
3366
+ schema:
3367
+ type: object
3368
+ required:
3369
+ - data
3370
+ - meta
3371
+ properties:
3372
+ data:
3373
+ $ref: "#/components/schemas/APIKeyCreateResponse"
3374
+ meta:
3375
+ $ref: "#/components/schemas/ResponseMeta"
3376
+ "400":
3377
+ $ref: "#/components/responses/InvalidJSON"
3378
+ "401":
3379
+ $ref: "#/components/responses/UnauthorizedManagement"
3380
+ "403":
3381
+ $ref: "#/components/responses/ForbiddenScope"
3382
+ "422":
3383
+ $ref: "#/components/responses/ValidationError"
3384
+ /api/v1/events:
3385
+ get:
3386
+ operationId: listEvents
3387
+ tags: [events]
3388
+ summary: List audit-backed event records
3389
+ x-required-scopes: ["event:read"]
3390
+ security:
3391
+ - bearerAuth: []
3392
+ parameters:
3393
+ - $ref: "#/components/parameters/CursorParam"
3394
+ - $ref: "#/components/parameters/LimitParam"
3395
+ - in: query
3396
+ name: event_type
3397
+ schema:
3398
+ type: string
3399
+ - in: query
3400
+ name: resource_type
3401
+ schema:
3402
+ type: string
3403
+ - in: query
3404
+ name: resource_id
3405
+ schema:
3406
+ type: string
3407
+ - in: query
3408
+ name: actor_type
3409
+ schema:
3410
+ $ref: "#/components/schemas/AuditActorType"
3411
+ responses:
3412
+ "200":
3413
+ description: Event feed page.
3414
+ content:
3415
+ application/json:
3416
+ schema:
3417
+ type: object
3418
+ required:
3419
+ - data
3420
+ - page_info
3421
+ - meta
3422
+ properties:
3423
+ data:
3424
+ type: array
3425
+ items:
3426
+ $ref: "#/components/schemas/Event"
3427
+ page_info:
3428
+ $ref: "#/components/schemas/EventPageInfo"
3429
+ meta:
3430
+ $ref: "#/components/schemas/ResponseMeta"
3431
+ "400":
3432
+ $ref: "#/components/responses/InvalidQuery"
3433
+ "401":
3434
+ $ref: "#/components/responses/UnauthorizedManagement"
3435
+ "403":
3436
+ $ref: "#/components/responses/ForbiddenScope"
3437
+ /api/v1/webhooks:
3438
+ get:
3439
+ operationId: listWebhookEndpoints
3440
+ tags: [webhooks]
3441
+ summary: List webhook endpoints
3442
+ x-required-scopes: ["webhook:write"]
3443
+ security:
3444
+ - bearerAuth: []
3445
+ parameters:
3446
+ - $ref: "#/components/parameters/LimitParam"
3447
+ responses:
3448
+ "200":
3449
+ description: Webhook endpoint list.
3450
+ content:
3451
+ application/json:
3452
+ schema:
3453
+ type: object
3454
+ required:
3455
+ - data
3456
+ - meta
3457
+ properties:
3458
+ data:
3459
+ type: array
3460
+ items:
3461
+ $ref: "#/components/schemas/WebhookEndpoint"
3462
+ meta:
3463
+ $ref: "#/components/schemas/ResponseMeta"
3464
+ "401":
3465
+ $ref: "#/components/responses/UnauthorizedManagement"
3466
+ "403":
3467
+ $ref: "#/components/responses/ForbiddenScope"
3468
+ post:
3469
+ operationId: createWebhookEndpoint
3470
+ tags: [webhooks]
3471
+ summary: Create a webhook endpoint
3472
+ x-required-scopes: ["webhook:write"]
3473
+ security:
3474
+ - bearerAuth: []
3475
+ requestBody:
3476
+ required: true
3477
+ content:
3478
+ application/json:
3479
+ schema:
3480
+ $ref: "#/components/schemas/WebhookEndpointCreateRequest"
3481
+ responses:
3482
+ "201":
3483
+ description: Webhook endpoint created. The raw secret is returned once.
3484
+ content:
3485
+ application/json:
3486
+ schema:
3487
+ type: object
3488
+ required:
3489
+ - data
3490
+ - meta
3491
+ properties:
3492
+ data:
3493
+ $ref: "#/components/schemas/WebhookEndpointWithSecret"
3494
+ meta:
3495
+ $ref: "#/components/schemas/ResponseMeta"
3496
+ "400":
3497
+ $ref: "#/components/responses/InvalidJSON"
3498
+ "401":
3499
+ $ref: "#/components/responses/UnauthorizedManagement"
3500
+ "403":
3501
+ $ref: "#/components/responses/ForbiddenScope"
3502
+ "409":
3503
+ $ref: "#/components/responses/Conflict"
3504
+ "422":
3505
+ $ref: "#/components/responses/ValidationError"
3506
+ /api/v1/webhooks/{id}:
3507
+ get:
3508
+ operationId: getWebhookEndpoint
3509
+ tags: [webhooks]
3510
+ summary: Get a webhook endpoint
3511
+ x-required-scopes: ["webhook:write"]
3512
+ security:
3513
+ - bearerAuth: []
3514
+ parameters:
3515
+ - $ref: "#/components/parameters/IDPath"
3516
+ responses:
3517
+ "200":
3518
+ description: Webhook endpoint record.
3519
+ content:
3520
+ application/json:
3521
+ schema:
3522
+ type: object
3523
+ required:
3524
+ - data
3525
+ - meta
3526
+ properties:
3527
+ data:
3528
+ $ref: "#/components/schemas/WebhookEndpoint"
3529
+ meta:
3530
+ $ref: "#/components/schemas/ResponseMeta"
3531
+ "401":
3532
+ $ref: "#/components/responses/UnauthorizedManagement"
3533
+ "403":
3534
+ $ref: "#/components/responses/ForbiddenScope"
3535
+ "404":
3536
+ $ref: "#/components/responses/NotFound"
3537
+ patch:
3538
+ operationId: updateWebhookEndpoint
3539
+ tags: [webhooks]
3540
+ summary: Update a webhook endpoint
3541
+ x-required-scopes: ["webhook:write"]
3542
+ security:
3543
+ - bearerAuth: []
3544
+ parameters:
3545
+ - $ref: "#/components/parameters/IDPath"
3546
+ requestBody:
3547
+ required: true
3548
+ content:
3549
+ application/json:
3550
+ schema:
3551
+ $ref: "#/components/schemas/WebhookEndpointUpdateRequest"
3552
+ responses:
3553
+ "200":
3554
+ description: Webhook endpoint updated. Secret rotations return `{webhook, secret}` inside `data`.
3555
+ content:
3556
+ application/json:
3557
+ schema:
3558
+ type: object
3559
+ required:
3560
+ - data
3561
+ - meta
3562
+ properties:
3563
+ data:
3564
+ oneOf:
3565
+ - $ref: "#/components/schemas/WebhookEndpoint"
3566
+ - $ref: "#/components/schemas/WebhookEndpointWithSecret"
3567
+ meta:
3568
+ $ref: "#/components/schemas/ResponseMeta"
3569
+ "400":
3570
+ $ref: "#/components/responses/InvalidJSON"
3571
+ "401":
3572
+ $ref: "#/components/responses/UnauthorizedManagement"
3573
+ "403":
3574
+ $ref: "#/components/responses/ForbiddenScope"
3575
+ "404":
3576
+ $ref: "#/components/responses/NotFound"
3577
+ "409":
3578
+ $ref: "#/components/responses/Conflict"
3579
+ "422":
3580
+ $ref: "#/components/responses/ValidationError"
3581
+ delete:
3582
+ operationId: deleteWebhookEndpoint
3583
+ tags: [webhooks]
3584
+ summary: Delete a webhook endpoint
3585
+ x-required-scopes: ["webhook:write"]
3586
+ security:
3587
+ - bearerAuth: []
3588
+ parameters:
3589
+ - $ref: "#/components/parameters/IDPath"
3590
+ responses:
3591
+ "204":
3592
+ description: Webhook endpoint deleted.
3593
+ "401":
3594
+ $ref: "#/components/responses/UnauthorizedManagement"
3595
+ "403":
3596
+ $ref: "#/components/responses/ForbiddenScope"
3597
+ "404":
3598
+ $ref: "#/components/responses/NotFound"
3599
+ /api/v1/licenses:
3600
+ get:
3601
+ operationId: listLicenses
3602
+ tags: [licenses]
3603
+ summary: List licenses
3604
+ x-required-scopes: ["license:read"]
3605
+ security:
3606
+ - bearerAuth: []
3607
+ parameters:
3608
+ - $ref: "#/components/parameters/LimitParam"
3609
+ - in: query
3610
+ name: product_id
3611
+ schema:
3612
+ type: string
3613
+ - in: query
3614
+ name: policy_id
3615
+ schema:
3616
+ type: string
3617
+ - in: query
3618
+ name: customer_id
3619
+ schema:
3620
+ type: string
3621
+ - in: query
3622
+ name: status
3623
+ schema:
3624
+ $ref: "#/components/schemas/LicenseStatus"
3625
+ - in: query
3626
+ name: order_id
3627
+ schema:
3628
+ type: string
3629
+ - in: query
3630
+ name: subscription_id
3631
+ schema:
3632
+ type: string
3633
+ - in: query
3634
+ name: expires_before
3635
+ schema:
3636
+ type: string
3637
+ format: date-time
3638
+ - in: query
3639
+ name: expires_after
3640
+ schema:
3641
+ type: string
3642
+ format: date-time
3643
+ responses:
3644
+ "200":
3645
+ description: License list.
3646
+ content:
3647
+ application/json:
3648
+ schema:
3649
+ type: object
3650
+ required:
3651
+ - data
3652
+ - meta
3653
+ properties:
3654
+ data:
3655
+ type: array
3656
+ items:
3657
+ $ref: "#/components/schemas/License"
3658
+ meta:
3659
+ $ref: "#/components/schemas/ResponseMeta"
3660
+ "400":
3661
+ $ref: "#/components/responses/InvalidQuery"
3662
+ "401":
3663
+ $ref: "#/components/responses/UnauthorizedManagement"
3664
+ "403":
3665
+ $ref: "#/components/responses/ForbiddenScope"
3666
+ post:
3667
+ operationId: createLicense
3668
+ tags: [licenses]
3669
+ summary: Create a license
3670
+ description: |
3671
+ Validated origin linkage is persisted on the license.
3672
+ If `order_id` is supplied and that order already links to a subscription,
3673
+ the license's stored `subscription_id` is inferred automatically when omitted.
3674
+ x-required-scopes: ["license:write"]
3675
+ security:
3676
+ - bearerAuth: []
3677
+ requestBody:
3678
+ required: true
3679
+ content:
3680
+ application/json:
3681
+ schema:
3682
+ $ref: "#/components/schemas/LicenseCreateRequest"
3683
+ responses:
3684
+ "201":
3685
+ description: License created. The raw license key is returned once.
3686
+ content:
3687
+ application/json:
3688
+ schema:
3689
+ type: object
3690
+ required:
3691
+ - data
3692
+ - meta
3693
+ properties:
3694
+ data:
3695
+ $ref: "#/components/schemas/LicenseCreateResponse"
3696
+ meta:
3697
+ $ref: "#/components/schemas/ResponseMeta"
3698
+ "400":
3699
+ $ref: "#/components/responses/InvalidJSON"
3700
+ "401":
3701
+ $ref: "#/components/responses/UnauthorizedManagement"
3702
+ "403":
3703
+ $ref: "#/components/responses/ForbiddenScope"
3704
+ "404":
3705
+ $ref: "#/components/responses/NotFound"
3706
+ "409":
3707
+ $ref: "#/components/responses/Conflict"
3708
+ "422":
3709
+ $ref: "#/components/responses/ValidationError"
3710
+ /api/v1/licenses/{id}:
3711
+ get:
3712
+ operationId: getLicense
3713
+ tags: [licenses]
3714
+ summary: Get a license
3715
+ x-required-scopes: ["license:read"]
3716
+ security:
3717
+ - bearerAuth: []
3718
+ parameters:
3719
+ - $ref: "#/components/parameters/IDPath"
3720
+ responses:
3721
+ "200":
3722
+ description: License record.
3723
+ content:
3724
+ application/json:
3725
+ schema:
3726
+ type: object
3727
+ required:
3728
+ - data
3729
+ - meta
3730
+ properties:
3731
+ data:
3732
+ $ref: "#/components/schemas/License"
3733
+ meta:
3734
+ $ref: "#/components/schemas/ResponseMeta"
3735
+ "401":
3736
+ $ref: "#/components/responses/UnauthorizedManagement"
3737
+ "403":
3738
+ $ref: "#/components/responses/ForbiddenScope"
3739
+ "404":
3740
+ $ref: "#/components/responses/NotFound"
3741
+ /api/v1/licenses/{id}/custom-fields:
3742
+ get:
3743
+ operationId: listLicenseCustomFieldValues
3744
+ tags: [custom-fields]
3745
+ summary: List license custom field values
3746
+ x-required-scopes: ["license:read"]
3747
+ security:
3748
+ - bearerAuth: []
3749
+ parameters:
3750
+ - $ref: "#/components/parameters/IDPath"
3751
+ - $ref: "#/components/parameters/LimitParam"
3752
+ responses:
3753
+ "200":
3754
+ description: License custom field values.
3755
+ content:
3756
+ application/json:
3757
+ schema:
3758
+ type: object
3759
+ required:
3760
+ - data
3761
+ - meta
3762
+ properties:
3763
+ data:
3764
+ type: array
3765
+ items:
3766
+ $ref: "#/components/schemas/CustomFieldValue"
3767
+ meta:
3768
+ $ref: "#/components/schemas/ResponseMeta"
3769
+ "401":
3770
+ $ref: "#/components/responses/UnauthorizedManagement"
3771
+ "403":
3772
+ $ref: "#/components/responses/ForbiddenScope"
3773
+ "404":
3774
+ $ref: "#/components/responses/NotFound"
3775
+ /api/v1/licenses/{id}/custom-fields/{field_id}:
3776
+ put:
3777
+ operationId: upsertLicenseCustomFieldValue
3778
+ tags: [custom-fields]
3779
+ summary: Upsert a license custom field value
3780
+ x-required-scopes: ["license:write"]
3781
+ security:
3782
+ - bearerAuth: []
3783
+ parameters:
3784
+ - $ref: "#/components/parameters/IDPath"
3785
+ - $ref: "#/components/parameters/FieldIDPath"
3786
+ requestBody:
3787
+ required: true
3788
+ content:
3789
+ application/json:
3790
+ schema:
3791
+ $ref: "#/components/schemas/CustomFieldValueUpsertRequest"
3792
+ responses:
3793
+ "200":
3794
+ description: License custom field value written.
3795
+ content:
3796
+ application/json:
3797
+ schema:
3798
+ type: object
3799
+ required:
3800
+ - data
3801
+ - meta
3802
+ properties:
3803
+ data:
3804
+ $ref: "#/components/schemas/CustomFieldValue"
3805
+ meta:
3806
+ $ref: "#/components/schemas/ResponseMeta"
3807
+ "204":
3808
+ description: License custom field value cleared.
3809
+ "400":
3810
+ $ref: "#/components/responses/InvalidJSON"
3811
+ "401":
3812
+ $ref: "#/components/responses/UnauthorizedManagement"
3813
+ "403":
3814
+ $ref: "#/components/responses/ForbiddenScope"
3815
+ "404":
3816
+ $ref: "#/components/responses/NotFound"
3817
+ "409":
3818
+ $ref: "#/components/responses/Conflict"
3819
+ "422":
3820
+ $ref: "#/components/responses/ValidationError"
3821
+ /api/v1/licenses/{id}/renew:
3822
+ post:
3823
+ operationId: renewLicense
3824
+ tags: [licenses]
3825
+ summary: Renew or extend a renewable license
3826
+ description: |
3827
+ Renewals are idempotent per license and `Idempotency-Key`.
3828
+ Exactly one of `expires_at` or `extend_by_days` is required.
3829
+ Renewal-source `order_id` and `subscription_id` are validated and recorded in audit metadata,
3830
+ but do not rewrite the stored origin linkage already persisted on the license.
3831
+ x-required-scopes: ["license:write"]
3832
+ security:
3833
+ - bearerAuth: []
3834
+ parameters:
3835
+ - $ref: "#/components/parameters/IDPath"
3836
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
3837
+ requestBody:
3838
+ required: true
3839
+ content:
3840
+ application/json:
3841
+ schema:
3842
+ $ref: "#/components/schemas/LicenseRenewRequest"
3843
+ responses:
3844
+ "200":
3845
+ description: License renewed.
3846
+ content:
3847
+ application/json:
3848
+ schema:
3849
+ type: object
3850
+ required:
3851
+ - data
3852
+ - meta
3853
+ properties:
3854
+ data:
3855
+ $ref: "#/components/schemas/License"
3856
+ meta:
3857
+ $ref: "#/components/schemas/ResponseMeta"
3858
+ "400":
3859
+ $ref: "#/components/responses/BadRequest"
3860
+ "401":
3861
+ $ref: "#/components/responses/UnauthorizedManagement"
3862
+ "403":
3863
+ $ref: "#/components/responses/ForbiddenScope"
3864
+ "404":
3865
+ $ref: "#/components/responses/NotFound"
3866
+ "409":
3867
+ $ref: "#/components/responses/Conflict"
3868
+ "422":
3869
+ $ref: "#/components/responses/ValidationError"
3870
+ /api/v1/licenses/{id}/devices:
3871
+ get:
3872
+ operationId: listLicenseDevices
3873
+ tags: [devices]
3874
+ summary: List devices for a license
3875
+ x-required-scopes: ["license:read"]
3876
+ security:
3877
+ - bearerAuth: []
3878
+ parameters:
3879
+ - $ref: "#/components/parameters/IDPath"
3880
+ - $ref: "#/components/parameters/LimitParam"
3881
+ responses:
3882
+ "200":
3883
+ description: Device list.
3884
+ content:
3885
+ application/json:
3886
+ schema:
3887
+ type: object
3888
+ required:
3889
+ - data
3890
+ - meta
3891
+ properties:
3892
+ data:
3893
+ type: array
3894
+ items:
3895
+ $ref: "#/components/schemas/Device"
3896
+ meta:
3897
+ $ref: "#/components/schemas/ResponseMeta"
3898
+ "401":
3899
+ $ref: "#/components/responses/UnauthorizedManagement"
3900
+ "403":
3901
+ $ref: "#/components/responses/ForbiddenScope"
3902
+ "404":
3903
+ $ref: "#/components/responses/NotFound"
3904
+ /api/v1/licenses/{id}/devices/{device_id}:
3905
+ get:
3906
+ operationId: getLicenseDevice
3907
+ tags: [devices]
3908
+ summary: Get a device for a license
3909
+ x-required-scopes: ["license:read"]
3910
+ security:
3911
+ - bearerAuth: []
3912
+ parameters:
3913
+ - $ref: "#/components/parameters/IDPath"
3914
+ - $ref: "#/components/parameters/DeviceIDPath"
3915
+ responses:
3916
+ "200":
3917
+ description: Device record.
3918
+ content:
3919
+ application/json:
3920
+ schema:
3921
+ type: object
3922
+ required:
3923
+ - data
3924
+ - meta
3925
+ properties:
3926
+ data:
3927
+ $ref: "#/components/schemas/Device"
3928
+ meta:
3929
+ $ref: "#/components/schemas/ResponseMeta"
3930
+ "401":
3931
+ $ref: "#/components/responses/UnauthorizedManagement"
3932
+ "403":
3933
+ $ref: "#/components/responses/ForbiddenScope"
3934
+ "404":
3935
+ $ref: "#/components/responses/NotFound"
3936
+ /api/v1/licenses/{id}/devices/{device_id}/reset:
3937
+ post:
3938
+ operationId: resetLicenseDevice
3939
+ tags: [devices]
3940
+ summary: Reset a managed device and clear its active state
3941
+ x-required-scopes: ["device:write"]
3942
+ security:
3943
+ - bearerAuth: []
3944
+ parameters:
3945
+ - $ref: "#/components/parameters/IDPath"
3946
+ - $ref: "#/components/parameters/DeviceIDPath"
3947
+ responses:
3948
+ "200":
3949
+ description: Device reset.
3950
+ content:
3951
+ application/json:
3952
+ schema:
3953
+ type: object
3954
+ required:
3955
+ - data
3956
+ - meta
3957
+ properties:
3958
+ data:
3959
+ $ref: "#/components/schemas/Device"
3960
+ meta:
3961
+ $ref: "#/components/schemas/ResponseMeta"
3962
+ "401":
3963
+ $ref: "#/components/responses/UnauthorizedManagement"
3964
+ "403":
3965
+ $ref: "#/components/responses/ForbiddenScope"
3966
+ "404":
3967
+ $ref: "#/components/responses/NotFound"
3968
+ "409":
3969
+ $ref: "#/components/responses/Conflict"
3970
+ /api/v1/licenses/{id}/devices/{device_id}/blacklist:
3971
+ post:
3972
+ operationId: blacklistLicenseDevice
3973
+ tags: [devices]
3974
+ summary: Blacklist a managed device and block future reuse
3975
+ x-required-scopes: ["device:write"]
3976
+ security:
3977
+ - bearerAuth: []
3978
+ parameters:
3979
+ - $ref: "#/components/parameters/IDPath"
3980
+ - $ref: "#/components/parameters/DeviceIDPath"
3981
+ responses:
3982
+ "200":
3983
+ description: Device blacklisted.
3984
+ content:
3985
+ application/json:
3986
+ schema:
3987
+ type: object
3988
+ required:
3989
+ - data
3990
+ - meta
3991
+ properties:
3992
+ data:
3993
+ $ref: "#/components/schemas/Device"
3994
+ meta:
3995
+ $ref: "#/components/schemas/ResponseMeta"
3996
+ "401":
3997
+ $ref: "#/components/responses/UnauthorizedManagement"
3998
+ "403":
3999
+ $ref: "#/components/responses/ForbiddenScope"
4000
+ "404":
4001
+ $ref: "#/components/responses/NotFound"
4002
+ "409":
4003
+ $ref: "#/components/responses/Conflict"
4004
+ /api/v1/licenses/{id}/suspend:
4005
+ post:
4006
+ operationId: suspendLicense
4007
+ tags: [licenses]
4008
+ summary: Suspend a license
4009
+ x-required-scopes: ["license:write"]
4010
+ security:
4011
+ - bearerAuth: []
4012
+ parameters:
4013
+ - $ref: "#/components/parameters/IDPath"
4014
+ responses:
4015
+ "200":
4016
+ description: License suspended or already suspended.
4017
+ content:
4018
+ application/json:
4019
+ schema:
4020
+ type: object
4021
+ required:
4022
+ - data
4023
+ - meta
4024
+ properties:
4025
+ data:
4026
+ $ref: "#/components/schemas/License"
4027
+ meta:
4028
+ $ref: "#/components/schemas/ResponseMeta"
4029
+ "401":
4030
+ $ref: "#/components/responses/UnauthorizedManagement"
4031
+ "403":
4032
+ $ref: "#/components/responses/ForbiddenScope"
4033
+ "404":
4034
+ $ref: "#/components/responses/NotFound"
4035
+ "409":
4036
+ $ref: "#/components/responses/Conflict"
4037
+ /api/v1/licenses/{id}/reinstate:
4038
+ post:
4039
+ operationId: reinstateLicense
4040
+ tags: [licenses]
4041
+ summary: Reinstate a suspended license
4042
+ x-required-scopes: ["license:write"]
4043
+ security:
4044
+ - bearerAuth: []
4045
+ parameters:
4046
+ - $ref: "#/components/parameters/IDPath"
4047
+ responses:
4048
+ "200":
4049
+ description: License reinstated or already active.
4050
+ content:
4051
+ application/json:
4052
+ schema:
4053
+ type: object
4054
+ required:
4055
+ - data
4056
+ - meta
4057
+ properties:
4058
+ data:
4059
+ $ref: "#/components/schemas/License"
4060
+ meta:
4061
+ $ref: "#/components/schemas/ResponseMeta"
4062
+ "401":
4063
+ $ref: "#/components/responses/UnauthorizedManagement"
4064
+ "403":
4065
+ $ref: "#/components/responses/ForbiddenScope"
4066
+ "404":
4067
+ $ref: "#/components/responses/NotFound"
4068
+ "409":
4069
+ $ref: "#/components/responses/Conflict"
4070
+ /api/v1/licenses/{id}/revoke:
4071
+ post:
4072
+ operationId: revokeLicense
4073
+ tags: [licenses]
4074
+ summary: Revoke a license and clear active seats
4075
+ x-required-scopes: ["license:write"]
4076
+ security:
4077
+ - bearerAuth: []
4078
+ parameters:
4079
+ - $ref: "#/components/parameters/IDPath"
4080
+ responses:
4081
+ "200":
4082
+ description: License revoked.
4083
+ content:
4084
+ application/json:
4085
+ schema:
4086
+ type: object
4087
+ required:
4088
+ - data
4089
+ - meta
4090
+ properties:
4091
+ data:
4092
+ $ref: "#/components/schemas/License"
4093
+ meta:
4094
+ $ref: "#/components/schemas/ResponseMeta"
4095
+ "401":
4096
+ $ref: "#/components/responses/UnauthorizedManagement"
4097
+ "403":
4098
+ $ref: "#/components/responses/ForbiddenScope"
4099
+ "404":
4100
+ $ref: "#/components/responses/NotFound"
4101
+ /api/v1/licenses/{id}/transfer:
4102
+ post:
4103
+ operationId: transferLicense
4104
+ tags: [licenses]
4105
+ summary: Transfer a license to another assignee
4106
+ x-required-scopes: ["license:write"]
4107
+ security:
4108
+ - bearerAuth: []
4109
+ parameters:
4110
+ - $ref: "#/components/parameters/IDPath"
4111
+ - $ref: "#/components/parameters/IdempotencyKeyHeader"
4112
+ requestBody:
4113
+ required: true
4114
+ content:
4115
+ application/json:
4116
+ schema:
4117
+ $ref: "#/components/schemas/LicenseTransferRequest"
4118
+ responses:
4119
+ "200":
4120
+ description: License transferred.
4121
+ content:
4122
+ application/json:
4123
+ schema:
4124
+ type: object
4125
+ required:
4126
+ - data
4127
+ - meta
4128
+ properties:
4129
+ data:
4130
+ $ref: "#/components/schemas/License"
4131
+ meta:
4132
+ $ref: "#/components/schemas/ResponseMeta"
4133
+ "400":
4134
+ $ref: "#/components/responses/BadRequest"
4135
+ "401":
4136
+ $ref: "#/components/responses/UnauthorizedManagement"
4137
+ "403":
4138
+ $ref: "#/components/responses/ForbiddenScope"
4139
+ "404":
4140
+ $ref: "#/components/responses/NotFound"
4141
+ "409":
4142
+ $ref: "#/components/responses/Conflict"
4143
+ "422":
4144
+ $ref: "#/components/responses/ValidationError"
4145
+ /api/v1/licenses/{id}/features:
4146
+ get:
4147
+ operationId: listLicenseFeatures
4148
+ tags: [features]
4149
+ summary: List assigned features for a license
4150
+ x-required-scopes: ["license:read"]
4151
+ security:
4152
+ - bearerAuth: []
4153
+ parameters:
4154
+ - $ref: "#/components/parameters/IDPath"
4155
+ - $ref: "#/components/parameters/LimitParam"
4156
+ responses:
4157
+ "200":
4158
+ description: License feature list.
4159
+ content:
4160
+ application/json:
4161
+ schema:
4162
+ type: object
4163
+ required:
4164
+ - data
4165
+ - meta
4166
+ properties:
4167
+ data:
4168
+ type: array
4169
+ items:
4170
+ $ref: "#/components/schemas/LicenseFeature"
4171
+ meta:
4172
+ $ref: "#/components/schemas/ResponseMeta"
4173
+ "401":
4174
+ $ref: "#/components/responses/UnauthorizedManagement"
4175
+ "403":
4176
+ $ref: "#/components/responses/ForbiddenScope"
4177
+ post:
4178
+ operationId: assignLicenseFeature
4179
+ tags: [features]
4180
+ summary: Assign or update a feature on a license
4181
+ x-required-scopes: ["license:write"]
4182
+ security:
4183
+ - bearerAuth: []
4184
+ parameters:
4185
+ - $ref: "#/components/parameters/IDPath"
4186
+ requestBody:
4187
+ required: true
4188
+ content:
4189
+ application/json:
4190
+ schema:
4191
+ $ref: "#/components/schemas/LicenseFeatureAssignRequest"
4192
+ responses:
4193
+ "200":
4194
+ description: License feature assignment written.
4195
+ content:
4196
+ application/json:
4197
+ schema:
4198
+ type: object
4199
+ required:
4200
+ - data
4201
+ - meta
4202
+ properties:
4203
+ data:
4204
+ $ref: "#/components/schemas/LicenseFeature"
4205
+ meta:
4206
+ $ref: "#/components/schemas/ResponseMeta"
4207
+ "400":
4208
+ $ref: "#/components/responses/InvalidJSON"
4209
+ "401":
4210
+ $ref: "#/components/responses/UnauthorizedManagement"
4211
+ "403":
4212
+ $ref: "#/components/responses/ForbiddenScope"
4213
+ "404":
4214
+ $ref: "#/components/responses/NotFound"
4215
+ "409":
4216
+ $ref: "#/components/responses/Conflict"
4217
+ "422":
4218
+ $ref: "#/components/responses/ValidationError"
4219
+ /api/v1/licenses/{id}/features/{feature_id}:
4220
+ delete:
4221
+ operationId: removeLicenseFeature
4222
+ tags: [features]
4223
+ summary: Remove a feature assignment from a license
4224
+ x-required-scopes: ["license:write"]
4225
+ security:
4226
+ - bearerAuth: []
4227
+ parameters:
4228
+ - $ref: "#/components/parameters/IDPath"
4229
+ - $ref: "#/components/parameters/FeatureIDPath"
4230
+ responses:
4231
+ "204":
4232
+ description: License feature removed.
4233
+ "401":
4234
+ $ref: "#/components/responses/UnauthorizedManagement"
4235
+ "403":
4236
+ $ref: "#/components/responses/ForbiddenScope"
4237
+ "404":
4238
+ $ref: "#/components/responses/NotFound"
4239
+ /api/v1/licenses/{id}/usage/reset:
4240
+ post:
4241
+ operationId: resetLicenseUsage
4242
+ tags: [features]
4243
+ summary: Reset or top up metered feature usage
4244
+ x-required-scopes: ["license:write"]
4245
+ security:
4246
+ - bearerAuth: []
4247
+ parameters:
4248
+ - $ref: "#/components/parameters/IDPath"
4249
+ requestBody:
4250
+ required: true
4251
+ content:
4252
+ application/json:
4253
+ schema:
4254
+ $ref: "#/components/schemas/LicenseFeatureUsageResetRequest"
4255
+ responses:
4256
+ "200":
4257
+ description: License feature usage updated.
4258
+ content:
4259
+ application/json:
4260
+ schema:
4261
+ type: object
4262
+ required:
4263
+ - data
4264
+ - meta
4265
+ properties:
4266
+ data:
4267
+ $ref: "#/components/schemas/LicenseFeature"
4268
+ meta:
4269
+ $ref: "#/components/schemas/ResponseMeta"
4270
+ "400":
4271
+ $ref: "#/components/responses/InvalidJSON"
4272
+ "401":
4273
+ $ref: "#/components/responses/UnauthorizedManagement"
4274
+ "403":
4275
+ $ref: "#/components/responses/ForbiddenScope"
4276
+ "404":
4277
+ $ref: "#/components/responses/NotFound"
4278
+ "409":
4279
+ $ref: "#/components/responses/Conflict"
4280
+ "422":
4281
+ $ref: "#/components/responses/ValidationError"
4282
+ /health:
4283
+ get:
4284
+ operationId: health
4285
+ tags: [system]
4286
+ summary: Hosted-safe liveness probe
4287
+ security: []
4288
+ responses:
4289
+ "200":
4290
+ description: Service is alive.
4291
+ content:
4292
+ application/json:
4293
+ schema:
4294
+ type: object
4295
+ required:
4296
+ - data
4297
+ - meta
4298
+ properties:
4299
+ data:
4300
+ $ref: "#/components/schemas/HealthData"
4301
+ meta:
4302
+ $ref: "#/components/schemas/ResponseMeta"
4303
+ /healthz:
4304
+ get:
4305
+ operationId: healthz
4306
+ tags: [system]
4307
+ summary: Liveness probe
4308
+ security: []
4309
+ responses:
4310
+ "200":
4311
+ description: Service is alive.
4312
+ content:
4313
+ application/json:
4314
+ schema:
4315
+ type: object
4316
+ required:
4317
+ - data
4318
+ - meta
4319
+ properties:
4320
+ data:
4321
+ $ref: "#/components/schemas/HealthData"
4322
+ meta:
4323
+ $ref: "#/components/schemas/ResponseMeta"
4324
+ /readyz:
4325
+ get:
4326
+ operationId: readyz
4327
+ tags: [system]
4328
+ summary: Readiness probe
4329
+ security: []
4330
+ responses:
4331
+ "200":
4332
+ description: Service is ready.
4333
+ content:
4334
+ application/json:
4335
+ schema:
4336
+ type: object
4337
+ required:
4338
+ - data
4339
+ - meta
4340
+ properties:
4341
+ data:
4342
+ $ref: "#/components/schemas/ReadyData"
4343
+ meta:
4344
+ $ref: "#/components/schemas/ResponseMeta"
4345
+ "503":
4346
+ description: Service is not ready.
4347
+ content:
4348
+ application/json:
4349
+ schema:
4350
+ type: object
4351
+ required:
4352
+ - data
4353
+ - meta
4354
+ properties:
4355
+ data:
4356
+ $ref: "#/components/schemas/ReadyData"
4357
+ meta:
4358
+ $ref: "#/components/schemas/ResponseMeta"
4359
+ /metrics:
4360
+ get:
4361
+ operationId: getMetrics
4362
+ tags: [system]
4363
+ summary: Prometheus metrics
4364
+ security: []
4365
+ responses:
4366
+ "200":
4367
+ description: Prometheus metrics payload.
4368
+ content:
4369
+ text/plain:
4370
+ schema:
4371
+ type: string
4372
+ /api/v1/system/public-keys:
4373
+ get:
4374
+ operationId: listPublicKeys
4375
+ tags: [system]
4376
+ summary: List public signing keys
4377
+ security: []
4378
+ responses:
4379
+ "200":
4380
+ description: Active and retired public signing keys.
4381
+ content:
4382
+ application/json:
4383
+ schema:
4384
+ type: object
4385
+ required:
4386
+ - data
4387
+ - meta
4388
+ properties:
4389
+ data:
4390
+ type: array
4391
+ items:
4392
+ $ref: "#/components/schemas/PublicKey"
4393
+ meta:
4394
+ $ref: "#/components/schemas/ResponseMeta"