@knowledge-stack/ksapi 1.163.0 → 2.4.2

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.
Files changed (153) hide show
  1. package/.openapi-generator/FILES +20 -2
  2. package/README.md +13 -3
  3. package/dist/apis/BillingApi.d.ts +70 -0
  4. package/dist/apis/BillingApi.js +120 -0
  5. package/dist/apis/DocumentVersionsApi.d.ts +8 -8
  6. package/dist/apis/DocumentVersionsApi.js +4 -4
  7. package/dist/apis/DocumentsApi.d.ts +4 -4
  8. package/dist/apis/DocumentsApi.js +2 -2
  9. package/dist/apis/SubscriptionsApi.d.ts +17 -20
  10. package/dist/apis/SubscriptionsApi.js +6 -9
  11. package/dist/apis/TenantsApi.d.ts +4 -4
  12. package/dist/apis/TenantsApi.js +2 -2
  13. package/dist/apis/TrashApi.d.ts +39 -1
  14. package/dist/apis/TrashApi.js +48 -0
  15. package/dist/apis/WorkflowRunsApi.d.ts +4 -4
  16. package/dist/apis/WorkflowRunsApi.js +2 -2
  17. package/dist/apis/index.d.ts +1 -0
  18. package/dist/apis/index.js +1 -0
  19. package/dist/esm/apis/BillingApi.d.ts +70 -0
  20. package/dist/esm/apis/BillingApi.js +83 -0
  21. package/dist/esm/apis/DocumentVersionsApi.d.ts +8 -8
  22. package/dist/esm/apis/DocumentVersionsApi.js +4 -4
  23. package/dist/esm/apis/DocumentsApi.d.ts +4 -4
  24. package/dist/esm/apis/DocumentsApi.js +2 -2
  25. package/dist/esm/apis/SubscriptionsApi.d.ts +17 -20
  26. package/dist/esm/apis/SubscriptionsApi.js +7 -10
  27. package/dist/esm/apis/TenantsApi.d.ts +4 -4
  28. package/dist/esm/apis/TenantsApi.js +2 -2
  29. package/dist/esm/apis/TrashApi.d.ts +39 -1
  30. package/dist/esm/apis/TrashApi.js +49 -1
  31. package/dist/esm/apis/WorkflowRunsApi.d.ts +4 -4
  32. package/dist/esm/apis/WorkflowRunsApi.js +2 -2
  33. package/dist/esm/apis/index.d.ts +1 -0
  34. package/dist/esm/apis/index.js +1 -0
  35. package/dist/esm/models/BillingInterval.d.ts +25 -0
  36. package/dist/esm/models/BillingInterval.js +43 -0
  37. package/dist/esm/models/BillingPaymentResponse.d.ts +100 -0
  38. package/dist/esm/models/BillingPaymentResponse.js +75 -0
  39. package/dist/esm/models/BillingSystem.d.ts +30 -0
  40. package/dist/esm/models/BillingSystem.js +48 -0
  41. package/dist/esm/models/ChangeSubscriptionRequest.d.ts +34 -0
  42. package/dist/esm/models/ChangeSubscriptionRequest.js +10 -0
  43. package/dist/esm/models/CheckoutAction.d.ts +27 -0
  44. package/dist/esm/models/CheckoutAction.js +45 -0
  45. package/dist/esm/models/CheckoutResponse.d.ts +76 -0
  46. package/dist/esm/models/{SubmitSubscriptionResponse.js → CheckoutResponse.js} +20 -20
  47. package/dist/esm/models/CreateWorkflowDefinitionRequest.d.ts +19 -0
  48. package/dist/esm/models/CreateWorkflowDefinitionRequest.js +10 -0
  49. package/dist/esm/models/IdpConfig.d.ts +6 -0
  50. package/dist/esm/models/IdpConfig.js +10 -1
  51. package/dist/esm/models/PaginatedResponseBillingPaymentResponse.d.ts +66 -0
  52. package/dist/esm/models/PaginatedResponseBillingPaymentResponse.js +70 -0
  53. package/dist/esm/models/ScheduleCadence.d.ts +32 -0
  54. package/dist/esm/models/ScheduleCadence.js +50 -0
  55. package/dist/esm/models/SubscriptionPlanResponse.d.ts +24 -0
  56. package/dist/esm/models/SubscriptionPlanResponse.js +8 -0
  57. package/dist/esm/models/{SubmitSubscriptionResponse.d.ts → TenantSubscriptionResponse.d.ts} +49 -38
  58. package/dist/esm/models/TenantSubscriptionResponse.js +67 -0
  59. package/dist/esm/models/TrashItemDetailResponse.d.ts +110 -0
  60. package/dist/esm/models/TrashItemDetailResponse.js +81 -0
  61. package/dist/esm/models/TrashItemResponse.d.ts +7 -0
  62. package/dist/esm/models/TrashItemResponse.js +3 -0
  63. package/dist/esm/models/UpdateWorkflowDefinitionRequest.d.ts +19 -0
  64. package/dist/esm/models/UpdateWorkflowDefinitionRequest.js +10 -0
  65. package/dist/esm/models/WorkflowDefinitionResponse.d.ts +19 -0
  66. package/dist/esm/models/WorkflowDefinitionResponse.js +7 -0
  67. package/dist/esm/models/index.d.ts +9 -1
  68. package/dist/esm/models/index.js +9 -1
  69. package/dist/models/BillingInterval.d.ts +25 -0
  70. package/dist/models/BillingInterval.js +51 -0
  71. package/dist/models/BillingPaymentResponse.d.ts +100 -0
  72. package/dist/models/BillingPaymentResponse.js +83 -0
  73. package/dist/models/BillingSystem.d.ts +30 -0
  74. package/dist/models/BillingSystem.js +56 -0
  75. package/dist/models/ChangeSubscriptionRequest.d.ts +34 -0
  76. package/dist/models/ChangeSubscriptionRequest.js +10 -0
  77. package/dist/models/CheckoutAction.d.ts +27 -0
  78. package/dist/models/CheckoutAction.js +53 -0
  79. package/dist/models/CheckoutResponse.d.ts +76 -0
  80. package/dist/models/{SubmitSubscriptionResponse.js → CheckoutResponse.js} +26 -26
  81. package/dist/models/CreateWorkflowDefinitionRequest.d.ts +19 -0
  82. package/dist/models/CreateWorkflowDefinitionRequest.js +10 -0
  83. package/dist/models/IdpConfig.d.ts +6 -0
  84. package/dist/models/IdpConfig.js +10 -1
  85. package/dist/models/PaginatedResponseBillingPaymentResponse.d.ts +66 -0
  86. package/dist/models/PaginatedResponseBillingPaymentResponse.js +78 -0
  87. package/dist/models/ScheduleCadence.d.ts +32 -0
  88. package/dist/models/ScheduleCadence.js +58 -0
  89. package/dist/models/SubscriptionPlanResponse.d.ts +24 -0
  90. package/dist/models/SubscriptionPlanResponse.js +8 -0
  91. package/dist/models/{SubmitSubscriptionResponse.d.ts → TenantSubscriptionResponse.d.ts} +49 -38
  92. package/dist/models/TenantSubscriptionResponse.js +75 -0
  93. package/dist/models/TrashItemDetailResponse.d.ts +110 -0
  94. package/dist/models/TrashItemDetailResponse.js +89 -0
  95. package/dist/models/TrashItemResponse.d.ts +7 -0
  96. package/dist/models/TrashItemResponse.js +3 -0
  97. package/dist/models/UpdateWorkflowDefinitionRequest.d.ts +19 -0
  98. package/dist/models/UpdateWorkflowDefinitionRequest.js +10 -0
  99. package/dist/models/WorkflowDefinitionResponse.d.ts +19 -0
  100. package/dist/models/WorkflowDefinitionResponse.js +7 -0
  101. package/dist/models/index.d.ts +9 -1
  102. package/dist/models/index.js +9 -1
  103. package/docs/BillingApi.md +90 -0
  104. package/docs/BillingInterval.md +33 -0
  105. package/docs/BillingPaymentResponse.md +51 -0
  106. package/docs/BillingSystem.md +33 -0
  107. package/docs/ChangeSubscriptionRequest.md +9 -1
  108. package/docs/CheckoutAction.md +33 -0
  109. package/docs/CheckoutResponse.md +41 -0
  110. package/docs/CreateWorkflowDefinitionRequest.md +6 -0
  111. package/docs/DocumentVersionsApi.md +2 -2
  112. package/docs/DocumentsApi.md +1 -1
  113. package/docs/FolderResponseOrDocumentResponseOrWorkflowDefinitionResponseOrWorkflowRunResponseOrDataSourceResponseOrDataSourceSchemaR.md +6 -0
  114. package/docs/IdpConfig.md +2 -0
  115. package/docs/PaginatedResponseBillingPaymentResponse.md +40 -0
  116. package/docs/ScheduleCadence.md +33 -0
  117. package/docs/SubscriptionPlanResponse.md +8 -0
  118. package/docs/SubscriptionsApi.md +7 -10
  119. package/docs/TenantSubscriptionResponse.md +47 -0
  120. package/docs/TenantsApi.md +1 -1
  121. package/docs/TrashApi.md +76 -0
  122. package/docs/TrashItemDetailResponse.md +55 -0
  123. package/docs/TrashItemResponse.md +2 -0
  124. package/docs/UpdateWorkflowDefinitionRequest.md +6 -0
  125. package/docs/WorkflowDefinitionResponse.md +6 -0
  126. package/docs/WorkflowRunsApi.md +1 -1
  127. package/package.json +1 -1
  128. package/src/apis/BillingApi.ts +142 -0
  129. package/src/apis/DocumentVersionsApi.ts +8 -8
  130. package/src/apis/DocumentsApi.ts +4 -4
  131. package/src/apis/SubscriptionsApi.ts +24 -31
  132. package/src/apis/TenantsApi.ts +4 -4
  133. package/src/apis/TrashApi.ts +86 -0
  134. package/src/apis/WorkflowRunsApi.ts +4 -4
  135. package/src/apis/index.ts +1 -0
  136. package/src/models/BillingInterval.ts +53 -0
  137. package/src/models/BillingPaymentResponse.ts +168 -0
  138. package/src/models/BillingSystem.ts +58 -0
  139. package/src/models/ChangeSubscriptionRequest.ts +55 -0
  140. package/src/models/CheckoutAction.ts +55 -0
  141. package/src/models/{SubmitSubscriptionResponse.ts → CheckoutResponse.ts} +61 -47
  142. package/src/models/CreateWorkflowDefinitionRequest.ts +37 -0
  143. package/src/models/IdpConfig.ts +14 -0
  144. package/src/models/PaginatedResponseBillingPaymentResponse.ts +130 -0
  145. package/src/models/ScheduleCadence.ts +60 -0
  146. package/src/models/SubscriptionPlanResponse.ts +32 -0
  147. package/src/models/TenantSubscriptionResponse.ts +159 -0
  148. package/src/models/TrashItemDetailResponse.ts +194 -0
  149. package/src/models/TrashItemResponse.ts +15 -0
  150. package/src/models/UpdateWorkflowDefinitionRequest.ts +37 -0
  151. package/src/models/WorkflowDefinitionResponse.ts +31 -0
  152. package/src/models/index.ts +9 -1
  153. package/docs/SubmitSubscriptionResponse.md +0 -39
@@ -909,7 +909,7 @@ example().catch(console.error);
909
909
 
910
910
  Workflow Run Callback Handler
911
911
 
912
- Terminal-state write seam for the in-process agent runner. The gating Temporal activities ``mark_run_completed_activity`` and ``mark_run_failed_activity`` authenticate as the triggering user (via ``assume_user``) and POST here. Only the user who triggered the run (or OWNER/ADMIN) may write its terminal state. The handler is idempotent: a callback against an already-terminal row returns ``already_terminal`` and the activity-level retry treats it as a no-op.
912
+ Terminal-state write seam for the in-process agent runner. The gating Temporal activities ``mark_run_completed_activity`` and ``mark_run_failed_activity`` authenticate as the triggering user (via ``assume_user``) and POST here. Only the user who triggered the run (or OWNER/ADMIN) may write its terminal state. The handler is idempotent: a callback against an already-terminal row returns ``already_terminal`` and the activity-level retry treats it as a no-op. On the first terminal transition it emails the run\'s triggering user (``run.user_id``) a completion or failure notification. Only already-loaded columns are captured in-session; recipient/language lookups and the send run post-commit and best-effort, so a rolled-back transaction never notifies and a notification failure never fails the callback.
913
913
 
914
914
  ### Example
915
915
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowledge-stack/ksapi",
3
- "version": "1.163.0",
3
+ "version": "2.4.2",
4
4
  "description": "OpenAPI client for @knowledge-stack/ksapi",
5
5
  "author": "OpenAPI-Generator",
6
6
  "repository": {
@@ -0,0 +1,142 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Knowledge Stack API
5
+ * Knowledge Stack backend API for authentication and knowledge management. ## Integrating (RPA / machine clients) **Base URL.** Knowledge Stack is self-hosted — point at your own deployment host (see `servers`). The `localhost` entry is for local development only. **Authentication.** Send `Authorization: Bearer <api-key>` on every request. Mint an API key once via `POST /v1/api-keys` from a signed-in browser session; the raw `sk-user-...` secret is returned **only** at creation, so store it then. A key inherits its owning user\'s live tenant role and path permissions — create RPA keys from a least-privilege user, and set `expires_at` for rotation. The `ks_uat` cookie scheme is browser-only and cannot be used by headless clients. **Async work is polled, not pushed.** There are no outbound webhooks. - `POST /v1/documents/ingest` returns `201` immediately with a `workflow_id`; poll `GET /v1/system-jobs/document_versions/{workflow_id}` until `status` is terminal (anything other than `pending`/`processing`). The `Location` response header points at this poll resource. - `POST /v1/workflow-runs/{run_id}/start` returns `202`; poll `GET /v1/workflow-runs/{run_id}` until `execution_state` is `COMPLETED` or `FAILED`. The `Location` header points at the run resource. - `POST /v1/agent/ask` is **synchronous** — it blocks until the agent finishes and returns the answer inline. Use a generous HTTP timeout. **Pagination.** List endpoints accept `limit`/`offset` and return `{items, total, limit, offset}`. **Errors.** Every non-2xx body is `{detail, code, request_id}`. `code` is a stable value from a closed set (see the `ErrorResponse` schema\'s `code` enum) — branch on it rather than parsing `detail`. Quota rejections return `429` with a `Retry-After` header; transient lock contention returns a retryable `503`. Quote `request_id` (also the `x-request-id` response header) to support. **Idempotency.** `POST /v1/workflow-runs` accepts an `idempotency_key` to dedupe retried run creation. `agent/ask` charges one message *before* running and does not refund a client-cancelled call.
6
+ *
7
+ * The version of the OpenAPI document: 0.1.0
8
+ *
9
+ *
10
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
11
+ * https://openapi-generator.tech
12
+ * Do not edit the class manually.
13
+ */
14
+
15
+
16
+ import * as runtime from '../runtime';
17
+ import type {
18
+ ErrorResponse,
19
+ HTTPValidationError,
20
+ PaginatedResponseBillingPaymentResponse,
21
+ } from '../models/index';
22
+ import {
23
+ ErrorResponseFromJSON,
24
+ ErrorResponseToJSON,
25
+ HTTPValidationErrorFromJSON,
26
+ HTTPValidationErrorToJSON,
27
+ PaginatedResponseBillingPaymentResponseFromJSON,
28
+ PaginatedResponseBillingPaymentResponseToJSON,
29
+ } from '../models/index';
30
+
31
+ export interface ListBillingPaymentsRequest {
32
+ tenantId: string;
33
+ limit?: number;
34
+ offset?: number;
35
+ }
36
+
37
+ /**
38
+ * BillingApi - interface
39
+ *
40
+ * @export
41
+ * @interface BillingApiInterface
42
+ */
43
+ export interface BillingApiInterface {
44
+ /**
45
+ * Creates request options for listBillingPayments without sending the request
46
+ * @param {string} tenantId
47
+ * @param {number} [limit] Number of items per page
48
+ * @param {number} [offset] Number of items to skip
49
+ * @throws {RequiredError}
50
+ * @memberof BillingApiInterface
51
+ */
52
+ listBillingPaymentsRequestOpts(requestParameters: ListBillingPaymentsRequest): Promise<runtime.RequestOpts>;
53
+
54
+ /**
55
+ * Newest-first payment history for the tenant (OWNER/ADMIN only). Backs the billing page\'s receipts list. ``invoice_url`` links the Stripe-hosted invoice when the payment ran through Stripe; CN (Ping++) payments render an in-app receipt from the row itself.
56
+ * @summary List Billing Payments Handler
57
+ * @param {string} tenantId
58
+ * @param {number} [limit] Number of items per page
59
+ * @param {number} [offset] Number of items to skip
60
+ * @param {*} [options] Override http request option.
61
+ * @throws {RequiredError}
62
+ * @memberof BillingApiInterface
63
+ */
64
+ listBillingPaymentsRaw(requestParameters: ListBillingPaymentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<PaginatedResponseBillingPaymentResponse>>;
65
+
66
+ /**
67
+ * Newest-first payment history for the tenant (OWNER/ADMIN only). Backs the billing page\'s receipts list. ``invoice_url`` links the Stripe-hosted invoice when the payment ran through Stripe; CN (Ping++) payments render an in-app receipt from the row itself.
68
+ * List Billing Payments Handler
69
+ */
70
+ listBillingPayments(requestParameters: ListBillingPaymentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<PaginatedResponseBillingPaymentResponse>;
71
+
72
+ }
73
+
74
+ /**
75
+ *
76
+ */
77
+ export class BillingApi extends runtime.BaseAPI implements BillingApiInterface {
78
+
79
+ /**
80
+ * Creates request options for listBillingPayments without sending the request
81
+ */
82
+ async listBillingPaymentsRequestOpts(requestParameters: ListBillingPaymentsRequest): Promise<runtime.RequestOpts> {
83
+ if (requestParameters['tenantId'] == null) {
84
+ throw new runtime.RequiredError(
85
+ 'tenantId',
86
+ 'Required parameter "tenantId" was null or undefined when calling listBillingPayments().'
87
+ );
88
+ }
89
+
90
+ const queryParameters: any = {};
91
+
92
+ if (requestParameters['limit'] != null) {
93
+ queryParameters['limit'] = requestParameters['limit'];
94
+ }
95
+
96
+ if (requestParameters['offset'] != null) {
97
+ queryParameters['offset'] = requestParameters['offset'];
98
+ }
99
+
100
+ const headerParameters: runtime.HTTPHeaders = {};
101
+
102
+ if (this.configuration && this.configuration.accessToken) {
103
+ const token = this.configuration.accessToken;
104
+ const tokenString = await token("bearerAuth", []);
105
+
106
+ if (tokenString) {
107
+ headerParameters["Authorization"] = `Bearer ${tokenString}`;
108
+ }
109
+ }
110
+
111
+ let urlPath = `/v1/tenants/{tenant_id}/billing/payments`;
112
+ urlPath = urlPath.replace(`{${"tenant_id"}}`, encodeURIComponent(String(requestParameters['tenantId'])));
113
+
114
+ return {
115
+ path: urlPath,
116
+ method: 'GET',
117
+ headers: headerParameters,
118
+ query: queryParameters,
119
+ };
120
+ }
121
+
122
+ /**
123
+ * Newest-first payment history for the tenant (OWNER/ADMIN only). Backs the billing page\'s receipts list. ``invoice_url`` links the Stripe-hosted invoice when the payment ran through Stripe; CN (Ping++) payments render an in-app receipt from the row itself.
124
+ * List Billing Payments Handler
125
+ */
126
+ async listBillingPaymentsRaw(requestParameters: ListBillingPaymentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<PaginatedResponseBillingPaymentResponse>> {
127
+ const requestOptions = await this.listBillingPaymentsRequestOpts(requestParameters);
128
+ const response = await this.request(requestOptions, initOverrides);
129
+
130
+ return new runtime.JSONApiResponse(response, (jsonValue) => PaginatedResponseBillingPaymentResponseFromJSON(jsonValue));
131
+ }
132
+
133
+ /**
134
+ * Newest-first payment history for the tenant (OWNER/ADMIN only). Backs the billing page\'s receipts list. ``invoice_url`` links the Stripe-hosted invoice when the payment ran through Stripe; CN (Ping++) payments render an in-app receipt from the row itself.
135
+ * List Billing Payments Handler
136
+ */
137
+ async listBillingPayments(requestParameters: ListBillingPaymentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<PaginatedResponseBillingPaymentResponse> {
138
+ const response = await this.listBillingPaymentsRaw(requestParameters, initOverrides);
139
+ return await response.value();
140
+ }
141
+
142
+ }
@@ -193,7 +193,7 @@ export interface DocumentVersionsApiInterface {
193
193
  createDocumentVersionRequestOpts(requestParameters: CreateDocumentVersionRequest): Promise<runtime.RequestOpts>;
194
194
 
195
195
  /**
196
- * Create a new version for a document. The version number is automatically incremented from the highest existing version.
196
+ * Create a new version for a document. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). The version number is automatically incremented from the highest existing version.
197
197
  * @summary Create Document Version Handler
198
198
  * @param {string} documentId Document ID
199
199
  * @param {*} [options] Override http request option.
@@ -203,7 +203,7 @@ export interface DocumentVersionsApiInterface {
203
203
  createDocumentVersionRaw(requestParameters: CreateDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<DocumentVersionResponse>>;
204
204
 
205
205
  /**
206
- * Create a new version for a document. The version number is automatically incremented from the highest existing version.
206
+ * Create a new version for a document. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). The version number is automatically incremented from the highest existing version.
207
207
  * Create Document Version Handler
208
208
  */
209
209
  createDocumentVersion(requestParameters: CreateDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<DocumentVersionResponse>;
@@ -217,7 +217,7 @@ export interface DocumentVersionsApiInterface {
217
217
  deleteDocumentVersionRequestOpts(requestParameters: DeleteDocumentVersionRequest): Promise<runtime.RequestOpts>;
218
218
 
219
219
  /**
220
- * Delete a document version by its ID. Cannot delete the active version of a document.
220
+ * Delete a document version by its ID. Requires an active document checkout held by the caller on the **parent document** (the version itself carries no lock). Acquire one via ``POST /v1/documents/{id}/checkout`` first; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Cannot delete the active version of a document.
221
221
  * @summary Delete Document Version Handler
222
222
  * @param {string} versionId DocumentVersion ID
223
223
  * @param {*} [options] Override http request option.
@@ -227,7 +227,7 @@ export interface DocumentVersionsApiInterface {
227
227
  deleteDocumentVersionRaw(requestParameters: DeleteDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>>;
228
228
 
229
229
  /**
230
- * Delete a document version by its ID. Cannot delete the active version of a document.
230
+ * Delete a document version by its ID. Requires an active document checkout held by the caller on the **parent document** (the version itself carries no lock). Acquire one via ``POST /v1/documents/{id}/checkout`` first; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Cannot delete the active version of a document.
231
231
  * Delete Document Version Handler
232
232
  */
233
233
  deleteDocumentVersion(requestParameters: DeleteDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void>;
@@ -615,7 +615,7 @@ export class DocumentVersionsApi extends runtime.BaseAPI implements DocumentVers
615
615
  }
616
616
 
617
617
  /**
618
- * Create a new version for a document. The version number is automatically incremented from the highest existing version.
618
+ * Create a new version for a document. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). The version number is automatically incremented from the highest existing version.
619
619
  * Create Document Version Handler
620
620
  */
621
621
  async createDocumentVersionRaw(requestParameters: CreateDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<DocumentVersionResponse>> {
@@ -626,7 +626,7 @@ export class DocumentVersionsApi extends runtime.BaseAPI implements DocumentVers
626
626
  }
627
627
 
628
628
  /**
629
- * Create a new version for a document. The version number is automatically incremented from the highest existing version.
629
+ * Create a new version for a document. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). The version number is automatically incremented from the highest existing version.
630
630
  * Create Document Version Handler
631
631
  */
632
632
  async createDocumentVersion(requestParameters: CreateDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<DocumentVersionResponse> {
@@ -670,7 +670,7 @@ export class DocumentVersionsApi extends runtime.BaseAPI implements DocumentVers
670
670
  }
671
671
 
672
672
  /**
673
- * Delete a document version by its ID. Cannot delete the active version of a document.
673
+ * Delete a document version by its ID. Requires an active document checkout held by the caller on the **parent document** (the version itself carries no lock). Acquire one via ``POST /v1/documents/{id}/checkout`` first; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Cannot delete the active version of a document.
674
674
  * Delete Document Version Handler
675
675
  */
676
676
  async deleteDocumentVersionRaw(requestParameters: DeleteDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
@@ -681,7 +681,7 @@ export class DocumentVersionsApi extends runtime.BaseAPI implements DocumentVers
681
681
  }
682
682
 
683
683
  /**
684
- * Delete a document version by its ID. Cannot delete the active version of a document.
684
+ * Delete a document version by its ID. Requires an active document checkout held by the caller on the **parent document** (the version itself carries no lock). Acquire one via ``POST /v1/documents/{id}/checkout`` first; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Cannot delete the active version of a document.
685
685
  * Delete Document Version Handler
686
686
  */
687
687
  async deleteDocumentVersion(requestParameters: DeleteDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {
@@ -436,7 +436,7 @@ export interface DocumentsApiInterface {
436
436
  ingestDocumentVersionRequestOpts(requestParameters: IngestDocumentVersionRequest): Promise<runtime.RequestOpts>;
437
437
 
438
438
  /**
439
- * Upload a new file for an existing document, creating a new version and triggering ingestion. Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
439
+ * Upload a new file for an existing document, creating a new version and triggering ingestion. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
440
440
  * @summary Ingest Document Version Handler
441
441
  * @param {string} documentId Document ID
442
442
  * @param {Blob} file
@@ -453,7 +453,7 @@ export interface DocumentsApiInterface {
453
453
  ingestDocumentVersionRaw(requestParameters: IngestDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<IngestDocumentResponse>>;
454
454
 
455
455
  /**
456
- * Upload a new file for an existing document, creating a new version and triggering ingestion. Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
456
+ * Upload a new file for an existing document, creating a new version and triggering ingestion. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
457
457
  * Ingest Document Version Handler
458
458
  */
459
459
  ingestDocumentVersion(requestParameters: IngestDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<IngestDocumentResponse>;
@@ -1261,7 +1261,7 @@ export class DocumentsApi extends runtime.BaseAPI implements DocumentsApiInterfa
1261
1261
  }
1262
1262
 
1263
1263
  /**
1264
- * Upload a new file for an existing document, creating a new version and triggering ingestion. Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
1264
+ * Upload a new file for an existing document, creating a new version and triggering ingestion. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
1265
1265
  * Ingest Document Version Handler
1266
1266
  */
1267
1267
  async ingestDocumentVersionRaw(requestParameters: IngestDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<IngestDocumentResponse>> {
@@ -1272,7 +1272,7 @@ export class DocumentsApi extends runtime.BaseAPI implements DocumentsApiInterfa
1272
1272
  }
1273
1273
 
1274
1274
  /**
1275
- * Upload a new file for an existing document, creating a new version and triggering ingestion. Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
1275
+ * Upload a new file for an existing document, creating a new version and triggering ingestion. Requires an active document checkout held by the caller. Acquire one via ``POST /v1/documents/{id}/checkout`` first and release it after; otherwise this returns 409 Conflict (\"A document checkout is required to edit this document.\"). Creates a new document version (incrementing the highest version number), uploads the file to S3, and starts the ingestion workflow. Upon successful ingestion, the new version is automatically activated (set as the document\'s active_version) and the old version\'s Qdrant points are deactivated. Returns 201 immediately with the Temporal ``workflow_id``. Ingestion runs in the background — poll ``GET /v1/system-jobs/document_versions/{workflow_id}`` (also given in the ``Location`` header) until ``status`` is terminal.
1276
1276
  * Ingest Document Version Handler
1277
1277
  */
1278
1278
  async ingestDocumentVersion(requestParameters: IngestDocumentVersionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<IngestDocumentResponse> {
@@ -16,28 +16,27 @@
16
16
  import * as runtime from '../runtime';
17
17
  import type {
18
18
  ChangeSubscriptionRequest,
19
+ CheckoutResponse,
19
20
  ErrorResponse,
20
21
  HTTPValidationError,
21
- SubmitSubscriptionResponse,
22
- SubscriptionPlanResponse,
22
+ TenantSubscriptionResponse,
23
23
  } from '../models/index';
24
24
  import {
25
25
  ChangeSubscriptionRequestFromJSON,
26
26
  ChangeSubscriptionRequestToJSON,
27
+ CheckoutResponseFromJSON,
28
+ CheckoutResponseToJSON,
27
29
  ErrorResponseFromJSON,
28
30
  ErrorResponseToJSON,
29
31
  HTTPValidationErrorFromJSON,
30
32
  HTTPValidationErrorToJSON,
31
- SubmitSubscriptionResponseFromJSON,
32
- SubmitSubscriptionResponseToJSON,
33
- SubscriptionPlanResponseFromJSON,
34
- SubscriptionPlanResponseToJSON,
33
+ TenantSubscriptionResponseFromJSON,
34
+ TenantSubscriptionResponseToJSON,
35
35
  } from '../models/index';
36
36
 
37
37
  export interface ChangeTenantSubscriptionRequest {
38
38
  tenantId: string;
39
39
  changeSubscriptionRequest: ChangeSubscriptionRequest;
40
- idempotencyKey?: string | null;
41
40
  }
42
41
 
43
42
  export interface GetTenantSubscriptionRequest {
@@ -55,29 +54,27 @@ export interface SubscriptionsApiInterface {
55
54
  * Creates request options for changeTenantSubscription without sending the request
56
55
  * @param {string} tenantId
57
56
  * @param {ChangeSubscriptionRequest} changeSubscriptionRequest
58
- * @param {string} [idempotencyKey]
59
57
  * @throws {RequiredError}
60
58
  * @memberof SubscriptionsApiInterface
61
59
  */
62
60
  changeTenantSubscriptionRequestOpts(requestParameters: ChangeTenantSubscriptionRequest): Promise<runtime.RequestOpts>;
63
61
 
64
62
  /**
65
- * Submit a subscription change (mock-Stripe). OWNER-only on the target tenant. Validates the request (tenant + plan exist, ``num_seats`` within bounds), submits the (mock-)Stripe subscription update, and returns 202. The plan/seat write is NOT applied here — that happens in ``POST /webhooks/stripe/subscription`` after Stripe confirms the change. Async two-hop workflow per ``docs/billing_additional_limits.md`` §\"Async payment workflow\": the dev environment exercises the same submit/webhook split as production will when the real Stripe SDK replaces the log-line stub in ``notify_billing``. Optional ``Idempotency-Key`` request header is forwarded to Stripe verbatim (clients that retry the same logical operation MUST send the same value across attempts; Stripe collapses duplicates server- side). Absent the header, the server generates a fresh ``uuid4()`` per call and emits a warning — but only when a Stripe call is actually about to fire (i.e. the validation passed AND the change is not a no-op). Warning before validation would false-positive on every 4xx and on every redundant submit. **Header value lands in structured logs.** The header value is forwarded into the ``stripe.update_subscription`` log event\'s ``idempotency_key`` field (and into the eventual real Stripe call). Use opaque random IDs (e.g. ``uuid4()``); do NOT pass user identifiers, tokens, or other sensitive material as the ``Idempotency-Key`` header.
63
+ * Start a subscription change (OWNER only). Priced plan validates the request, creates a provider checkout (Stripe Checkout redirect / Ping++ charge credential), and returns it nothing is written until the provider\'s webhook confirms payment. Free plan applied immediately for unbilled tenants, or scheduled for period end when a billed subscription is active (Stripe: ``cancel_at_period_end``; Ping++ prepay simply isn\'t renewed). Re-picking the current plan/seats while a Stripe cancellation is scheduled resumes the renewal. Deployments with no payment provider configured return 501 for priced checkouts (billing is optional local-first).
66
64
  * @summary Change Tenant Subscription Handler
67
65
  * @param {string} tenantId
68
66
  * @param {ChangeSubscriptionRequest} changeSubscriptionRequest
69
- * @param {string} [idempotencyKey]
70
67
  * @param {*} [options] Override http request option.
71
68
  * @throws {RequiredError}
72
69
  * @memberof SubscriptionsApiInterface
73
70
  */
74
- changeTenantSubscriptionRaw(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SubmitSubscriptionResponse>>;
71
+ changeTenantSubscriptionRaw(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<CheckoutResponse>>;
75
72
 
76
73
  /**
77
- * Submit a subscription change (mock-Stripe). OWNER-only on the target tenant. Validates the request (tenant + plan exist, ``num_seats`` within bounds), submits the (mock-)Stripe subscription update, and returns 202. The plan/seat write is NOT applied here — that happens in ``POST /webhooks/stripe/subscription`` after Stripe confirms the change. Async two-hop workflow per ``docs/billing_additional_limits.md`` §\"Async payment workflow\": the dev environment exercises the same submit/webhook split as production will when the real Stripe SDK replaces the log-line stub in ``notify_billing``. Optional ``Idempotency-Key`` request header is forwarded to Stripe verbatim (clients that retry the same logical operation MUST send the same value across attempts; Stripe collapses duplicates server- side). Absent the header, the server generates a fresh ``uuid4()`` per call and emits a warning — but only when a Stripe call is actually about to fire (i.e. the validation passed AND the change is not a no-op). Warning before validation would false-positive on every 4xx and on every redundant submit. **Header value lands in structured logs.** The header value is forwarded into the ``stripe.update_subscription`` log event\'s ``idempotency_key`` field (and into the eventual real Stripe call). Use opaque random IDs (e.g. ``uuid4()``); do NOT pass user identifiers, tokens, or other sensitive material as the ``Idempotency-Key`` header.
74
+ * Start a subscription change (OWNER only). Priced plan validates the request, creates a provider checkout (Stripe Checkout redirect / Ping++ charge credential), and returns it nothing is written until the provider\'s webhook confirms payment. Free plan applied immediately for unbilled tenants, or scheduled for period end when a billed subscription is active (Stripe: ``cancel_at_period_end``; Ping++ prepay simply isn\'t renewed). Re-picking the current plan/seats while a Stripe cancellation is scheduled resumes the renewal. Deployments with no payment provider configured return 501 for priced checkouts (billing is optional local-first).
78
75
  * Change Tenant Subscription Handler
79
76
  */
80
- changeTenantSubscription(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SubmitSubscriptionResponse>;
77
+ changeTenantSubscription(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<CheckoutResponse>;
81
78
 
82
79
  /**
83
80
  * Creates request options for getTenantSubscription without sending the request
@@ -88,20 +85,20 @@ export interface SubscriptionsApiInterface {
88
85
  getTenantSubscriptionRequestOpts(requestParameters: GetTenantSubscriptionRequest): Promise<runtime.RequestOpts>;
89
86
 
90
87
  /**
91
- * Read the tenant\'s current subscription plan, including private tiers. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. Returns the full plan body (id, name, caps, max_seats, public flag, timestamps). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
88
+ * Read the tenant\'s current subscription: plan body + period state. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. The period fields let the FE render renewal/expiry state (billed subscriptions carry the paid-through date; unbilled ones a 100-year horizon), and ``will_renew`` distinguishes an auto-renewing Stripe subscription from one whose cancellation is scheduled (or a prepay/unbilled period that simply runs out). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
92
89
  * @summary Get Tenant Subscription Handler
93
90
  * @param {string} tenantId
94
91
  * @param {*} [options] Override http request option.
95
92
  * @throws {RequiredError}
96
93
  * @memberof SubscriptionsApiInterface
97
94
  */
98
- getTenantSubscriptionRaw(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SubscriptionPlanResponse>>;
95
+ getTenantSubscriptionRaw(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<TenantSubscriptionResponse>>;
99
96
 
100
97
  /**
101
- * Read the tenant\'s current subscription plan, including private tiers. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. Returns the full plan body (id, name, caps, max_seats, public flag, timestamps). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
98
+ * Read the tenant\'s current subscription: plan body + period state. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. The period fields let the FE render renewal/expiry state (billed subscriptions carry the paid-through date; unbilled ones a 100-year horizon), and ``will_renew`` distinguishes an auto-renewing Stripe subscription from one whose cancellation is scheduled (or a prepay/unbilled period that simply runs out). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
102
99
  * Get Tenant Subscription Handler
103
100
  */
104
- getTenantSubscription(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SubscriptionPlanResponse>;
101
+ getTenantSubscription(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<TenantSubscriptionResponse>;
105
102
 
106
103
  }
107
104
 
@@ -134,10 +131,6 @@ export class SubscriptionsApi extends runtime.BaseAPI implements SubscriptionsAp
134
131
 
135
132
  headerParameters['Content-Type'] = 'application/json';
136
133
 
137
- if (requestParameters['idempotencyKey'] != null) {
138
- headerParameters['Idempotency-Key'] = String(requestParameters['idempotencyKey']);
139
- }
140
-
141
134
  if (this.configuration && this.configuration.accessToken) {
142
135
  const token = this.configuration.accessToken;
143
136
  const tokenString = await token("bearerAuth", []);
@@ -160,21 +153,21 @@ export class SubscriptionsApi extends runtime.BaseAPI implements SubscriptionsAp
160
153
  }
161
154
 
162
155
  /**
163
- * Submit a subscription change (mock-Stripe). OWNER-only on the target tenant. Validates the request (tenant + plan exist, ``num_seats`` within bounds), submits the (mock-)Stripe subscription update, and returns 202. The plan/seat write is NOT applied here — that happens in ``POST /webhooks/stripe/subscription`` after Stripe confirms the change. Async two-hop workflow per ``docs/billing_additional_limits.md`` §\"Async payment workflow\": the dev environment exercises the same submit/webhook split as production will when the real Stripe SDK replaces the log-line stub in ``notify_billing``. Optional ``Idempotency-Key`` request header is forwarded to Stripe verbatim (clients that retry the same logical operation MUST send the same value across attempts; Stripe collapses duplicates server- side). Absent the header, the server generates a fresh ``uuid4()`` per call and emits a warning — but only when a Stripe call is actually about to fire (i.e. the validation passed AND the change is not a no-op). Warning before validation would false-positive on every 4xx and on every redundant submit. **Header value lands in structured logs.** The header value is forwarded into the ``stripe.update_subscription`` log event\'s ``idempotency_key`` field (and into the eventual real Stripe call). Use opaque random IDs (e.g. ``uuid4()``); do NOT pass user identifiers, tokens, or other sensitive material as the ``Idempotency-Key`` header.
156
+ * Start a subscription change (OWNER only). Priced plan validates the request, creates a provider checkout (Stripe Checkout redirect / Ping++ charge credential), and returns it nothing is written until the provider\'s webhook confirms payment. Free plan applied immediately for unbilled tenants, or scheduled for period end when a billed subscription is active (Stripe: ``cancel_at_period_end``; Ping++ prepay simply isn\'t renewed). Re-picking the current plan/seats while a Stripe cancellation is scheduled resumes the renewal. Deployments with no payment provider configured return 501 for priced checkouts (billing is optional local-first).
164
157
  * Change Tenant Subscription Handler
165
158
  */
166
- async changeTenantSubscriptionRaw(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SubmitSubscriptionResponse>> {
159
+ async changeTenantSubscriptionRaw(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<CheckoutResponse>> {
167
160
  const requestOptions = await this.changeTenantSubscriptionRequestOpts(requestParameters);
168
161
  const response = await this.request(requestOptions, initOverrides);
169
162
 
170
- return new runtime.JSONApiResponse(response, (jsonValue) => SubmitSubscriptionResponseFromJSON(jsonValue));
163
+ return new runtime.JSONApiResponse(response, (jsonValue) => CheckoutResponseFromJSON(jsonValue));
171
164
  }
172
165
 
173
166
  /**
174
- * Submit a subscription change (mock-Stripe). OWNER-only on the target tenant. Validates the request (tenant + plan exist, ``num_seats`` within bounds), submits the (mock-)Stripe subscription update, and returns 202. The plan/seat write is NOT applied here — that happens in ``POST /webhooks/stripe/subscription`` after Stripe confirms the change. Async two-hop workflow per ``docs/billing_additional_limits.md`` §\"Async payment workflow\": the dev environment exercises the same submit/webhook split as production will when the real Stripe SDK replaces the log-line stub in ``notify_billing``. Optional ``Idempotency-Key`` request header is forwarded to Stripe verbatim (clients that retry the same logical operation MUST send the same value across attempts; Stripe collapses duplicates server- side). Absent the header, the server generates a fresh ``uuid4()`` per call and emits a warning — but only when a Stripe call is actually about to fire (i.e. the validation passed AND the change is not a no-op). Warning before validation would false-positive on every 4xx and on every redundant submit. **Header value lands in structured logs.** The header value is forwarded into the ``stripe.update_subscription`` log event\'s ``idempotency_key`` field (and into the eventual real Stripe call). Use opaque random IDs (e.g. ``uuid4()``); do NOT pass user identifiers, tokens, or other sensitive material as the ``Idempotency-Key`` header.
167
+ * Start a subscription change (OWNER only). Priced plan validates the request, creates a provider checkout (Stripe Checkout redirect / Ping++ charge credential), and returns it nothing is written until the provider\'s webhook confirms payment. Free plan applied immediately for unbilled tenants, or scheduled for period end when a billed subscription is active (Stripe: ``cancel_at_period_end``; Ping++ prepay simply isn\'t renewed). Re-picking the current plan/seats while a Stripe cancellation is scheduled resumes the renewal. Deployments with no payment provider configured return 501 for priced checkouts (billing is optional local-first).
175
168
  * Change Tenant Subscription Handler
176
169
  */
177
- async changeTenantSubscription(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SubmitSubscriptionResponse> {
170
+ async changeTenantSubscription(requestParameters: ChangeTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<CheckoutResponse> {
178
171
  const response = await this.changeTenantSubscriptionRaw(requestParameters, initOverrides);
179
172
  return await response.value();
180
173
  }
@@ -215,21 +208,21 @@ export class SubscriptionsApi extends runtime.BaseAPI implements SubscriptionsAp
215
208
  }
216
209
 
217
210
  /**
218
- * Read the tenant\'s current subscription plan, including private tiers. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. Returns the full plan body (id, name, caps, max_seats, public flag, timestamps). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
211
+ * Read the tenant\'s current subscription: plan body + period state. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. The period fields let the FE render renewal/expiry state (billed subscriptions carry the paid-through date; unbilled ones a 100-year horizon), and ``will_renew`` distinguishes an auto-renewing Stripe subscription from one whose cancellation is scheduled (or a prepay/unbilled period that simply runs out). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
219
212
  * Get Tenant Subscription Handler
220
213
  */
221
- async getTenantSubscriptionRaw(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SubscriptionPlanResponse>> {
214
+ async getTenantSubscriptionRaw(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<TenantSubscriptionResponse>> {
222
215
  const requestOptions = await this.getTenantSubscriptionRequestOpts(requestParameters);
223
216
  const response = await this.request(requestOptions, initOverrides);
224
217
 
225
- return new runtime.JSONApiResponse(response, (jsonValue) => SubscriptionPlanResponseFromJSON(jsonValue));
218
+ return new runtime.JSONApiResponse(response, (jsonValue) => TenantSubscriptionResponseFromJSON(jsonValue));
226
219
  }
227
220
 
228
221
  /**
229
- * Read the tenant\'s current subscription plan, including private tiers. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. Returns the full plan body (id, name, caps, max_seats, public flag, timestamps). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
222
+ * Read the tenant\'s current subscription: plan body + period state. Any active member of the tenant can read. This is the only path that surfaces private (custom enterprise) plans to non-admin users — ``GET /public/subscriptions`` filters them out, but tenants on a private plan still need to see their own caps. The period fields let the FE render renewal/expiry state (billed subscriptions carry the paid-through date; unbilled ones a 100-year horizon), and ``will_renew`` distinguishes an auto-renewing Stripe subscription from one whose cancellation is scheduled (or a prepay/unbilled period that simply runs out). Returns 404 when the user is not a member of the tenant — same response shape as a non-existent tenant so we don\'t leak existence to outsiders.
230
223
  * Get Tenant Subscription Handler
231
224
  */
232
- async getTenantSubscription(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SubscriptionPlanResponse> {
225
+ async getTenantSubscription(requestParameters: GetTenantSubscriptionRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<TenantSubscriptionResponse> {
233
226
  const response = await this.getTenantSubscriptionRaw(requestParameters, initOverrides);
234
227
  return await response.value();
235
228
  }
@@ -191,7 +191,7 @@ export interface TenantsApiInterface {
191
191
  deleteTenantRequestOpts(requestParameters: DeleteTenantRequest): Promise<runtime.RequestOpts>;
192
192
 
193
193
  /**
194
- * Delete a tenant. Requires OWNER role in the tenant. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
194
+ * Delete a tenant. Requires OWNER role in the tenant. Refused (409) while a provider-billed subscription is live — deleting the tenant would not stop Stripe/Ping++ from charging for it; the OWNER must downgrade to free (or let the prepay period expire) first. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
195
195
  * @summary Delete Tenant
196
196
  * @param {string} tenantId
197
197
  * @param {*} [options] Override http request option.
@@ -201,7 +201,7 @@ export interface TenantsApiInterface {
201
201
  deleteTenantRaw(requestParameters: DeleteTenantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>>;
202
202
 
203
203
  /**
204
- * Delete a tenant. Requires OWNER role in the tenant. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
204
+ * Delete a tenant. Requires OWNER role in the tenant. Refused (409) while a provider-billed subscription is live — deleting the tenant would not stop Stripe/Ping++ from charging for it; the OWNER must downgrade to free (or let the prepay period expire) first. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
205
205
  * Delete Tenant
206
206
  */
207
207
  deleteTenant(requestParameters: DeleteTenantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void>;
@@ -621,7 +621,7 @@ export class TenantsApi extends runtime.BaseAPI implements TenantsApiInterface {
621
621
  }
622
622
 
623
623
  /**
624
- * Delete a tenant. Requires OWNER role in the tenant. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
624
+ * Delete a tenant. Requires OWNER role in the tenant. Refused (409) while a provider-billed subscription is live — deleting the tenant would not stop Stripe/Ping++ from charging for it; the OWNER must downgrade to free (or let the prepay period expire) first. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
625
625
  * Delete Tenant
626
626
  */
627
627
  async deleteTenantRaw(requestParameters: DeleteTenantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<void>> {
@@ -632,7 +632,7 @@ export class TenantsApi extends runtime.BaseAPI implements TenantsApiInterface {
632
632
  }
633
633
 
634
634
  /**
635
- * Delete a tenant. Requires OWNER role in the tenant. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
635
+ * Delete a tenant. Requires OWNER role in the tenant. Refused (409) while a provider-billed subscription is live — deleting the tenant would not stop Stripe/Ping++ from charging for it; the OWNER must downgrade to free (or let the prepay period expire) first. Deletes the tenant\'s LiteLLM team/keys and S3 bucket after the DB transaction commits.
636
636
  * Delete Tenant
637
637
  */
638
638
  async deleteTenant(requestParameters: DeleteTenantRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<void> {