@siglume/api-sdk 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -134,6 +134,14 @@ the fee.
134
134
  `units_consumed` is kept for receipts and analytics; it does not multiply a
135
135
  request-type plan price.
136
136
 
137
+ For irreversible side effects such as posting to X, set
138
+ `billing_timing: "prepay"`. The platform first calls your API as a quote
139
+ (`execution_kind="quote"` / `dry_run=true`), reads `billingPreview.operation`
140
+ and `draftToken`, collects the direct payment for that pricing-plan operation,
141
+ then calls the ACTION endpoint with the same token as `commit_token`. If payment
142
+ fails, the ACTION call is never made. Use the default `"post"` timing only for
143
+ read-only or reversible usage.
144
+
137
145
  Company-name publishing is founder-only in the Phase 2 MVP. Use
138
146
  `publisher_type: "company"` with `company_id` in `app_manifest.yaml`, or pass
139
147
  `--company <company_id>` to the CLI. Paid company listings require the
@@ -1494,6 +1494,7 @@ function parseListing(data) {
1494
1494
  price_model: stringOrNull(data.price_model),
1495
1495
  price_value_minor: Number(data.price_value_minor ?? 0),
1496
1496
  pricing_plan,
1497
+ billing_timing: String(data.billing_timing ?? metadata.billing_timing ?? "post"),
1497
1498
  currency: String(data.currency ?? "USD"),
1498
1499
  allow_free_trial: Boolean(data.allow_free_trial ?? false),
1499
1500
  free_trial_duration_days: Number(data.free_trial_duration_days ?? 30),
@@ -2712,6 +2713,7 @@ var init_client = __esm({
2712
2713
  "price_model",
2713
2714
  "price_value_minor",
2714
2715
  "pricing_plan",
2716
+ "billing_timing",
2715
2717
  "currency",
2716
2718
  "allow_free_trial",
2717
2719
  "free_trial_duration_days",
@@ -2731,6 +2733,13 @@ var init_client = __esm({
2731
2733
  if (payload.pricing_plan !== void 0 && (typeof payload.pricing_plan !== "object" || Array.isArray(payload.pricing_plan))) {
2732
2734
  throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
2733
2735
  }
2736
+ if (payload.billing_timing !== void 0 && payload.billing_timing !== null) {
2737
+ const billingTiming = String(payload.billing_timing || "post").trim().toLowerCase();
2738
+ if (billingTiming !== "post" && billingTiming !== "prepay") {
2739
+ throw new SiglumeClientError("AppManifest.billing_timing must be 'post' or 'prepay'.");
2740
+ }
2741
+ payload.billing_timing = billingTiming;
2742
+ }
2734
2743
  if (payload.store_vertical === void 0 || payload.store_vertical === null) {
2735
2744
  throw new SiglumeClientError(
2736
2745
  "AppManifest.store_vertical is required. Choose 'api' for normal API Store listings or 'game' for API games."
@@ -6238,6 +6247,9 @@ var AppTestHarness = class {
6238
6247
  issues.push("at least one example_prompt is recommended");
6239
6248
  }
6240
6249
  issues.push(...pricingPlanFloorIssues(manifest.pricing_plan, String(manifest.currency ?? "USD")));
6250
+ if (manifest.billing_timing !== void 0 && manifest.billing_timing !== "post" && manifest.billing_timing !== "prepay") {
6251
+ issues.push("billing_timing must be 'post' or 'prepay'");
6252
+ }
6241
6253
  if ((manifest.price_model === PriceModel.USAGE_BASED || manifest.price_model === PriceModel.PER_ACTION) && (!manifest.pricing_plan || !Array.isArray(manifest.pricing_plan.items) || manifest.pricing_plan.items.length === 0)) {
6242
6254
  issues.push("pricing_plan.items is required for usage_based/per_action pricing");
6243
6255
  }