@clocknext/sdk 0.3.0 → 0.5.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/dist/index.d.cts CHANGED
@@ -8,12 +8,44 @@
8
8
  */
9
9
  type SignalType = "wallet" | "credit" | "outcome";
10
10
  type SignalStatus = "SUCCESS" | "FAILURE" | "PENDING";
11
- /** Token counts for a signal. All default to 0. */
11
+ /**
12
+ * Token counts for a signal. `input` and `output` are required — every metered
13
+ * call has them, and the server requires them. `cache` (provider-specific
14
+ * prompt-cache reads) is optional and defaults to 0 server-side when omitted.
15
+ */
12
16
  interface Tokens {
13
- input?: number;
14
- output?: number;
17
+ input: number;
18
+ output: number;
15
19
  cache?: number;
16
20
  }
21
+ /** The organisation + key behind a request — `cnk.workspace.me()`. */
22
+ interface WorkspaceIdentity {
23
+ organization: {
24
+ id: string;
25
+ name: string;
26
+ slug: string | null;
27
+ /** `sandbox` is a disposable staging twin; `live` bills for real. Check
28
+ * this before sending production traffic. */
29
+ environment: "sandbox" | "live";
30
+ };
31
+ apiKey: {
32
+ prefix: string;
33
+ lastFour: string;
34
+ expiresAt: string | null;
35
+ } | null;
36
+ }
37
+ /** One model the org has enabled — `cnk.workspace.models()`. The `modelId` is
38
+ * what you put in a signal's `model`. Prices are USD per 1,000,000 tokens. */
39
+ interface Model {
40
+ modelId: string;
41
+ modelName: string;
42
+ provider: string;
43
+ providerName: string;
44
+ isActive: boolean;
45
+ inputPrice: number;
46
+ outputPrice: number;
47
+ cachePrice: number;
48
+ }
17
49
  interface SignalBase {
18
50
  /** The customer this usage belongs to (required). */
19
51
  customerId: string;
@@ -22,14 +54,21 @@ interface SignalBase {
22
54
  * (Settings → Models). Matched case-insensitively against `OrgModel.modelId`.
23
55
  */
24
56
  model: string;
25
- /** Token counts for this call. */
26
- tokens?: Tokens;
57
+ /** Token counts for this call — required; every metered signal is priced on
58
+ * tokens. (`cache` within is optional; `input`/`output` are not.) */
59
+ tokens: Tokens;
27
60
  /** Optional member (email) this usage is attributed to. */
28
61
  member?: string;
29
- /** Defaults to SUCCESS. */
30
- status?: SignalStatus;
31
62
  /** Free-form metadata. Credit rules can target `custom.<key>` paths. */
32
63
  custom?: Record<string, unknown>;
64
+ /**
65
+ * Idempotency key for safe retries. **Auto-generated (UUID v4) if omitted**
66
+ * and reused across every retry of this signal, so a retried send is
67
+ * deduplicated server-side instead of double-recording. Supply your own — a
68
+ * stable id for this logical event — to also dedup across process restarts or
69
+ * at-least-once redelivery, which an in-memory auto key can't survive.
70
+ */
71
+ idempotencyKey?: string;
33
72
  }
34
73
  /** Meters a credit, identified by the credit's stable `agentKey`. */
35
74
  interface CreditSignal extends SignalBase {
@@ -64,6 +103,18 @@ interface SerializedOutcomeAttribution {
64
103
  progressSteps: string[];
65
104
  totalSteps: number;
66
105
  }
106
+ /** The customer's remaining balance for the dimension a signal metered, AFTER
107
+ * the signal was applied — update an on-screen meter straight from the record
108
+ * response. Populated on recorded (inline / `{ wait: true }`) signals; `null`
109
+ * on dry runs and on read-back. */
110
+ interface UsageBalance {
111
+ dimension: "credit" | "outcome" | "wallet";
112
+ /** Post-signal remaining. `null` when the meter is uncapped — an ARREAR
113
+ * (pay-as-you-go) credit or outcome has no fixed allowance. */
114
+ remaining: number | null;
115
+ /** The credit / outcome name; `null` for the wallet. */
116
+ name: string | null;
117
+ }
67
118
  interface SerializedUsageLog {
68
119
  id: string;
69
120
  customerId: string;
@@ -82,6 +133,9 @@ interface SerializedUsageLog {
82
133
  status: SignalStatus;
83
134
  appliedRules: SerializedRuleApplication[];
84
135
  outcome: SerializedOutcomeAttribution | null;
136
+ /** Post-signal balance for the metered dimension. Null on dry runs and
137
+ * read-back. */
138
+ balance: UsageBalance | null;
85
139
  createdAt: string;
86
140
  }
87
141
  /** Result of a single signal send (sync mode, or `{ wait: true }`). */
@@ -150,18 +204,55 @@ interface CustomerProfileInput {
150
204
  /** ISO 4217 (3 letters); must be enabled for the org. */
151
205
  currencyCode?: string;
152
206
  }
153
- /** `name` is required on create. */
207
+ /** `name` and `email` are required on create; every other field is optional. */
154
208
  type CreateCustomerInput = CustomerProfileInput & {
155
209
  name: string;
210
+ email: string;
156
211
  };
157
212
  interface CustomerList {
158
213
  customers: ApiCustomer[];
159
214
  nextCursor: string | null;
160
215
  }
161
- type RevenueRange = "30d" | "6m" | "1y" | "all";
162
- /** Loosely typed insight payloads (revenue/balances/plan) — server shapes the
163
- * detail; we surface the whole envelope minus the `ok` flag. */
164
- type CustomerBalances = {
216
+ /** One credit type's running balance for a customer (an element of
217
+ * `customers.balances().credits`). */
218
+ interface CreditBalance {
219
+ creditId: string;
220
+ /** The credit's stable agent key — the same key used to record usage and to
221
+ * adjust this balance. */
222
+ agentKey: string;
223
+ creditName: string;
224
+ granted: number;
225
+ used: number;
226
+ remaining: number;
227
+ }
228
+ /** One outcome's running balance for a customer. Unlike a credit balance it
229
+ * has no `used`, and it carries the outcome's ordered step list. */
230
+ interface OutcomeBalance {
231
+ outcomeId: string;
232
+ outcomeName: string;
233
+ granted: number;
234
+ remaining: number;
235
+ /** Each step's `agentKey` is what `signals.outcome()` and the outcome adjust
236
+ * API use to address this outcome (outcomes have no key of their own). */
237
+ steps: {
238
+ id: string;
239
+ name: string;
240
+ agentKey: string;
241
+ }[];
242
+ }
243
+ /** One unit's advance allowance for a customer. No `used` field. */
244
+ interface UnitBalance {
245
+ unitId: string;
246
+ /** The unit's stable agent key — the same key used to record usage and to
247
+ * adjust this balance. */
248
+ agentKey: string;
249
+ unitName: string;
250
+ granted: number;
251
+ remaining: number;
252
+ }
253
+ /** Wallet / credit / outcome / unit balances for a customer's active plan
254
+ * (`customers.balances()`). */
255
+ interface CustomerBalances {
165
256
  customerId: string;
166
257
  currency: {
167
258
  code: string;
@@ -171,34 +262,40 @@ type CustomerBalances = {
171
262
  wallet: {
172
263
  balanceUsd: number;
173
264
  } | null;
174
- credits: unknown[];
175
- outcomes: unknown[];
176
- units: unknown[];
177
- };
178
- type CustomerPlan = {
179
- customerId: string;
180
- currency: {
181
- code: string;
182
- rateUsd: number;
265
+ credits: CreditBalance[];
266
+ outcomes: OutcomeBalance[];
267
+ units: UnitBalance[];
268
+ }
269
+ /** The customer's active plan (the `plan` field of `customers.plan()`);
270
+ * `null` when the customer is unsubscribed. */
271
+ interface CustomerPlanDetails {
272
+ purchaseId: string;
273
+ planId: string | null;
274
+ planName: string;
275
+ planType: PlanType;
276
+ planKind: PlanKind;
277
+ seatScope: "CUSTOMER" | "MEMBER" | null;
278
+ billingCycle: BillingCycle;
279
+ cost: number;
280
+ status: "SCHEDULED" | "ACTIVE";
281
+ billingDate: string;
282
+ spendingLimit: number | null;
283
+ spentThisCycle: number | null;
284
+ meters: {
285
+ wallet: boolean;
286
+ credit: boolean;
287
+ outcome: boolean;
288
+ unit: boolean;
183
289
  };
184
- plan: Record<string, unknown> | null;
185
- };
186
- type CustomerRevenue = {
290
+ }
291
+ interface CustomerPlan {
187
292
  customerId: string;
188
- range: RevenueRange;
189
- window: unknown;
190
- bucket: unknown;
191
293
  currency: {
192
294
  code: string;
193
295
  rateUsd: number;
194
296
  };
195
- revenue: number;
196
- cost: number;
197
- profit: number;
198
- grossMargin: number;
199
- deltas: Record<string, unknown>;
200
- trend: unknown[];
201
- };
297
+ plan: CustomerPlanDetails | null;
298
+ }
202
299
  interface PortalTokenInput {
203
300
  customerId: string;
204
301
  ttlSeconds?: number;
@@ -219,18 +316,68 @@ type PlanKind = "FLAT_PRICE" | "PAY_AS_YOU_GO" | "PAY_PER_SEAT";
219
316
  type ComponentType = "WALLET" | "CREDIT" | "OUTCOME" | "UNIT" | "FLAT";
220
317
  /** ADVANCE bills up-front for the cycle; ARREAR bills for what was consumed. */
221
318
  type BillingMode = "ADVANCE" | "ARREAR";
222
- /** One entitlement line in a plan. Set the id matching `type` (creditId for CREDIT, …). */
223
- interface PlanComponentInput {
224
- type: ComponentType;
319
+ /** Prepaid USD wallet. `amount` is the funded balance (required). Max one
320
+ * wallet component per plan. */
321
+ interface WalletComponentInput {
322
+ type: "WALLET";
225
323
  billingMode: BillingMode;
226
- creditId?: string | null;
227
- outcomeId?: string | null;
228
- unitId?: string | null;
229
- /** Granted quantity (ADVANCE components). */
230
- quantity?: number | null;
231
- /** Flat amount (FLAT / WALLET components). */
232
- amount?: number | null;
324
+ amount: number;
325
+ }
326
+ /** A one-off flat fee — `amount` is required. Max one flat component per plan;
327
+ * not allowed on FREE plans. */
328
+ interface FlatComponentInput {
329
+ type: "FLAT";
330
+ billingMode: BillingMode;
331
+ amount: number;
233
332
  }
333
+ /** A credit entitlement, referenced by `creditId`. Billed ADVANCE it needs a
334
+ * granted `quantity`; billed ARREAR it meters usage with no upfront grant. */
335
+ type CreditComponentInput = {
336
+ type: "CREDIT";
337
+ billingMode: "ADVANCE";
338
+ creditId: string;
339
+ quantity: number;
340
+ } | {
341
+ type: "CREDIT";
342
+ billingMode: "ARREAR";
343
+ creditId: string;
344
+ quantity?: number | null;
345
+ };
346
+ /** An outcome entitlement, referenced by `outcomeId`. ADVANCE needs a granted
347
+ * `quantity`; ARREAR meters usage. */
348
+ type OutcomeComponentInput = {
349
+ type: "OUTCOME";
350
+ billingMode: "ADVANCE";
351
+ outcomeId: string;
352
+ quantity: number;
353
+ } | {
354
+ type: "OUTCOME";
355
+ billingMode: "ARREAR";
356
+ outcomeId: string;
357
+ quantity?: number | null;
358
+ };
359
+ /** A unit entitlement, referenced by `unitId`. ADVANCE needs a granted
360
+ * `quantity`; ARREAR meters usage. */
361
+ type UnitComponentInput = {
362
+ type: "UNIT";
363
+ billingMode: "ADVANCE";
364
+ unitId: string;
365
+ quantity: number;
366
+ } | {
367
+ type: "UNIT";
368
+ billingMode: "ARREAR";
369
+ unitId: string;
370
+ quantity?: number | null;
371
+ };
372
+ /**
373
+ * One entitlement line in a plan — a discriminated union on `type` (and, where
374
+ * it matters, `billingMode`) so the per-type fields the server requires are
375
+ * enforced at compile time instead of surfacing as runtime 422s:
376
+ * - CREDIT / OUTCOME / UNIT require their matching id;
377
+ * - CREDIT / OUTCOME / UNIT require `quantity` when billed ADVANCE;
378
+ * - WALLET / FLAT require `amount`.
379
+ */
380
+ type PlanComponentInput = WalletComponentInput | FlatComponentInput | CreditComponentInput | OutcomeComponentInput | UnitComponentInput;
234
381
  interface CreatePlanInput {
235
382
  name: string;
236
383
  description?: string | null;
@@ -264,6 +411,8 @@ interface Plan {
264
411
  kind: PlanKind;
265
412
  billingCycle: BillingCycle;
266
413
  cost: number;
414
+ /** Signed adjustment applied to the plan's headline price (default 0). */
415
+ priceAdjustment: number;
267
416
  currencyCode: string;
268
417
  isActive: boolean;
269
418
  components: PlanComponent[];
@@ -274,6 +423,7 @@ interface PlanDetail extends Plan {
274
423
  createdByName: string | null;
275
424
  customerCount: number;
276
425
  invoiceCount: number;
426
+ openInvoiceCount: number;
277
427
  stats: {
278
428
  totalInvoiced: number;
279
429
  totalCollected: number;
@@ -296,6 +446,7 @@ interface Purchase {
296
446
  purchaseNumber: string;
297
447
  customerId: string;
298
448
  customerName: string;
449
+ customerLogoUrl: string | null;
299
450
  planId: string | null;
300
451
  planName: string;
301
452
  planType: PlanType;
@@ -307,9 +458,12 @@ interface Purchase {
307
458
  cost: number;
308
459
  currencyCode: string;
309
460
  billingDate: string;
461
+ nextBillingDate: string;
310
462
  status: PurchaseStatus;
463
+ voidAfterMinutes: number;
311
464
  autoPayment: boolean;
312
465
  autoPaymentPauseReason: string | null;
466
+ notes: string | null;
313
467
  createdAt: string;
314
468
  }
315
469
  /** The purchase returned by `purchases.get()` — a different, detail-oriented shape. */
@@ -327,7 +481,10 @@ interface PurchaseDetail {
327
481
  customer: {
328
482
  id: string;
329
483
  name: string;
484
+ logoUrl: string | null;
330
485
  };
486
+ voidAfterMinutes: number;
487
+ notes: string | null;
331
488
  autoPayment: boolean;
332
489
  autoPaymentPauseReason: string | null;
333
490
  autoPaymentPausedAt: string | null;
@@ -522,33 +679,78 @@ interface WalletEntryInput {
522
679
  amount: number;
523
680
  notes?: string;
524
681
  }
525
- /** Grant (positive) or claw back (negative) a credit balance. `delta` must be a non-zero whole number. */
682
+ /** Grant (positive) or claw back (negative) a credit balance. `delta` must be a
683
+ * non-zero whole number. The credit is addressed by its stable `agentKey`. */
526
684
  interface CreditAdjustInput {
527
- creditId: string;
685
+ /** The credit's stable agent key (the same key used to record usage). */
686
+ agentKey: string;
528
687
  delta: number;
529
688
  notes?: string;
530
689
  }
531
- /** Grant/claw an outcome balance. `delta` is a non-zero whole number; floored at 0. */
690
+ /** Grant/claw an outcome balance. `delta` is a non-zero whole number; floored at
691
+ * 0. The outcome is addressed by a STEP's `agentKey` (outcomes have no key of
692
+ * their own). */
532
693
  interface OutcomeAdjustInput {
533
- outcomeId: string;
694
+ /** An outcome step's stable agent key — identifies the parent outcome. */
695
+ agentKey: string;
534
696
  delta: number;
535
697
  notes?: string;
536
698
  }
537
- /** Grant/claw a unit balance. `delta` is non-zero (fractional allowed); floored at 0. */
699
+ /** Grant/claw a unit balance. `delta` is non-zero (fractional allowed); floored
700
+ * at 0. The unit is addressed by its stable `agentKey`. */
538
701
  interface UnitAdjustInput {
539
- unitId: string;
702
+ /** The unit's stable agent key (the same key used to record usage). */
703
+ agentKey: string;
540
704
  delta: number;
541
705
  notes?: string;
542
706
  }
543
707
  /** A per-model token bundle attached to a credit or outcome step. */
544
708
  interface ModelBundleEntry {
545
709
  orgModelId: string;
546
- modelName: string;
710
+ /** Display label; the server defaults it from the model when omitted. */
711
+ modelName?: string;
547
712
  tokens: number;
548
713
  input: number;
549
714
  output: number;
550
715
  cache: number;
551
716
  }
717
+ /** One point on a cost-over-time analytics series. */
718
+ interface CostPoint {
719
+ /** UTC day, `YYYY-MM-DD`. */
720
+ dateIso: string;
721
+ /** Short display label, e.g. "Jun 24". */
722
+ label: string;
723
+ /** Average cost that day, or `null` on days with no usage. */
724
+ cost: number | null;
725
+ reqs: number;
726
+ }
727
+ /** Summary stats across a cost-over-time series. */
728
+ interface CostStats {
729
+ activeDays: number;
730
+ avgCost: number | null;
731
+ peakCost: number | null;
732
+ troughCost: number | null;
733
+ deviationPct: number | null;
734
+ }
735
+ /** Cost-over-time analytics for a credit (`credits.get().analytics`). */
736
+ interface CreditAnalytics {
737
+ basePrice: number;
738
+ pricePerCredit: number;
739
+ marginPercent: number;
740
+ points: CostPoint[];
741
+ stats: CostStats;
742
+ }
743
+ /** Cost-over-time analytics for an outcome (`outcomes.get().analytics`).
744
+ * Each point adds `completions` (workflows finished that day). */
745
+ interface OutcomeAnalytics {
746
+ basePrice: number;
747
+ pricePerOutcome: number;
748
+ marginPercent: number;
749
+ points: (CostPoint & {
750
+ completions: number;
751
+ })[];
752
+ stats: CostStats;
753
+ }
552
754
  interface Credit {
553
755
  id: string;
554
756
  name: string;
@@ -573,8 +775,7 @@ interface CreditDetail extends Credit {
573
775
  revenue: number;
574
776
  usageLogCount: number;
575
777
  };
576
- /** Cost-over-time analytics; shape is server-defined. */
577
- analytics: Record<string, unknown>;
778
+ analytics: CreditAnalytics;
578
779
  }
579
780
  interface CreateCreditInput {
580
781
  name: string;
@@ -623,7 +824,7 @@ interface OutcomeDetail extends Outcome {
623
824
  completed: number;
624
825
  totalRemaining: number;
625
826
  };
626
- analytics: Record<string, unknown>;
827
+ analytics: OutcomeAnalytics;
627
828
  }
628
829
  interface CreateOutcomeInput {
629
830
  name: string;
@@ -651,6 +852,9 @@ interface UnitTier {
651
852
  }
652
853
  interface Unit {
653
854
  id: string;
855
+ /** Stable per-org report key — what `signals.unit({ agentKey })` sends.
856
+ * The ONLY identifier accepted when reporting unit consumption. */
857
+ agentKey: string;
654
858
  name: string;
655
859
  description: string | null;
656
860
  pricingType: UnitPricingType;
@@ -658,10 +862,23 @@ interface Unit {
658
862
  tiers: UnitTier[];
659
863
  isActive: boolean;
660
864
  createdAt: string;
865
+ createdByName: string | null;
866
+ }
867
+ /** One row in a unit's linked-customer sample (`units.get().customers`). */
868
+ interface UnitCustomerRow {
869
+ customerId: string;
870
+ name: string;
871
+ legalName: string | null;
872
+ slug: string;
873
+ logoUrl: string | null;
874
+ granted: number;
875
+ used: number;
876
+ remaining: number;
877
+ currentlyMetered: boolean;
661
878
  }
662
- /** `units.get()` — adds linked-customer sample plus stats. */
879
+ /** `units.get()` — adds linked-customer sample plus stats.
880
+ * `createdByName` is inherited from `Unit`. */
663
881
  interface UnitDetail extends Unit {
664
- createdByName: string | null;
665
882
  stats: {
666
883
  planCount: number;
667
884
  customerCount: number;
@@ -669,27 +886,68 @@ interface UnitDetail extends Unit {
669
886
  totalUsed: number;
670
887
  };
671
888
  /** First page (≤10) of customers currently metered on this unit. */
672
- customers: Record<string, unknown>[];
889
+ customers: UnitCustomerRow[];
673
890
  }
674
- interface CreateUnitInput {
891
+ /** Flat per-event pricing — a single `flatPrice` (defaults to 0), no tiers. */
892
+ interface FlatUnitInput {
675
893
  name: string;
676
- pricingType: UnitPricingType;
677
- /** Required for FLAT pricing. */
894
+ /** Stable per-org report key (`signals.unit({ agentKey })`); `[a-z0-9._-]`. */
895
+ agentKey: string;
896
+ pricingType: "FLAT";
897
+ /** Price per event; defaults to 0. */
678
898
  flatPrice?: number;
679
- /** Required for SLAB/VOLUME pricing (≤50 tiers). */
680
- tiers?: UnitTierInput[];
681
899
  description?: string | null;
682
900
  isActive?: boolean;
683
901
  }
902
+ /** Tiered pricing (SLAB or VOLUME) — at least one tier is required. */
903
+ interface TieredUnitInput {
904
+ name: string;
905
+ /** Stable per-org report key (`signals.unit({ agentKey })`); `[a-z0-9._-]`. */
906
+ agentKey: string;
907
+ pricingType: "SLAB" | "VOLUME";
908
+ /** At least one tier (≤50). Only the last tier may have `upTo: null`. */
909
+ tiers: UnitTierInput[];
910
+ description?: string | null;
911
+ isActive?: boolean;
912
+ }
913
+ /**
914
+ * Create a unit type — a discriminated union on `pricingType`: `FLAT` takes an
915
+ * optional `flatPrice` (defaults to 0); `SLAB`/`VOLUME` require `tiers`, so the
916
+ * server's "add at least one tier" rule is enforced at compile time.
917
+ */
918
+ type CreateUnitInput = FlatUnitInput | TieredUnitInput;
684
919
  type UpdateUnitInput = CreateUnitInput;
685
- /** Record one unit-metered event. `unit` matches a catalog unit name (case-insensitive). */
920
+ /**
921
+ * Record one unit-metered event. The unit is addressed by its `agentKey` (the
922
+ * stable key set when the unit was created) — the ONLY accepted identifier;
923
+ * the display name is deliberately not accepted, so a rename can never redirect
924
+ * a live integration. Keys are matched exactly (they are stored lowercased).
925
+ */
686
926
  interface UnitInput {
687
927
  customerId: string;
688
- unit: string;
928
+ agentKey: string;
689
929
  member?: string;
690
930
  }
931
+ /** One serialized unit-consumption event — the result of `signals.unit()` and
932
+ * each element of `UnitUsageList.events`. */
933
+ interface SerializedUnitUsage {
934
+ id: string;
935
+ customerId: string;
936
+ /** Display name of the unit. */
937
+ unit: string;
938
+ /** The unit's stable agent key; `null` if the unit was deleted. */
939
+ agentKey: string | null;
940
+ billingMode: BillingMode;
941
+ /** Remaining ADVANCE allowance after this event; `null` for ARREAR. */
942
+ remaining: number | null;
943
+ customerCost: number;
944
+ member: string | null;
945
+ createdAt: string;
946
+ }
691
947
  interface UnitUsageRow {
692
948
  unit: string;
949
+ /** The unit's stable agent key — what to send to report against it. */
950
+ agentKey: string | null;
693
951
  billingMode: BillingMode;
694
952
  granted?: number;
695
953
  used: number;
@@ -701,7 +959,7 @@ interface UnitUsageList {
701
959
  name: string;
702
960
  };
703
961
  units: UnitUsageRow[];
704
- events: unknown[];
962
+ events: SerializedUnitUsage[];
705
963
  }
706
964
  type ThresholdKind = "CREDIT" | "OUTCOME" | "WALLET";
707
965
  interface Webhook {
@@ -843,12 +1101,12 @@ declare class Credits {
843
1101
  list(params?: {
844
1102
  active?: boolean;
845
1103
  }): Promise<Credit[]>;
846
- /** Create a credit type. `POST /api/v1/credits`. */
847
- create(input: CreateCreditInput): Promise<void>;
1104
+ /** Create a credit type; returns the created credit. `POST /api/v1/credits`. */
1105
+ create(input: CreateCreditInput): Promise<Credit>;
848
1106
  /** Fetch one credit type with usage stats. `GET /api/v1/credits/:id`. */
849
1107
  get(id: string): Promise<CreditDetail>;
850
- /** Update a credit type's definition. `PATCH /api/v1/credits/:id`. */
851
- update(id: string, input: UpdateCreditInput): Promise<void>;
1108
+ /** Update a credit type's definition; returns the updated credit. `PATCH /api/v1/credits/:id`. */
1109
+ update(id: string, input: UpdateCreditInput): Promise<Credit>;
852
1110
  /** Activate or deactivate a credit type. */
853
1111
  setActive(id: string, isActive: boolean): Promise<Credit>;
854
1112
  /** Delete a credit type. Refused while a customer is linked to it. */
@@ -857,9 +1115,9 @@ declare class Credits {
857
1115
 
858
1116
  /**
859
1117
  * The `customers` resource — full CRUD over the org's customers plus the
860
- * read-only insight endpoints (usage / balances / plan / revenue). Every call
861
- * is scoped to the API key's organisation server-side; a customer in another
862
- * org resolves as a NotFoundError.
1118
+ * read-only insight endpoints (usage / balances / plan). Every call is scoped
1119
+ * to the API key's organisation server-side; a customer in another org
1120
+ * resolves as a NotFoundError.
863
1121
  */
864
1122
  declare class Customers {
865
1123
  private readonly transport;
@@ -886,18 +1144,39 @@ declare class Customers {
886
1144
  update(id: string, input: CustomerProfileInput): Promise<ApiCustomer>;
887
1145
  /** Delete a customer (members, invitations, usage logs cascade). */
888
1146
  delete(id: string): Promise<void>;
889
- /** A customer's usage history. `GET /api/v1/customers/:id/usage`. */
1147
+ /** A customer's usage history. `GET /api/v1/usage?customerId=`. */
890
1148
  usage(id: string, params?: {
891
1149
  limit?: number;
892
1150
  }): Promise<UsageList>;
893
1151
  /** Wallet / credit / outcome / unit balances. `GET …/:id/balances`. */
894
1152
  balances(id: string): Promise<CustomerBalances>;
1153
+ /**
1154
+ * One credit balance for a customer, matched by `creditId` or `creditName`;
1155
+ * `null` when the customer has no plan or no matching credit. Convenience
1156
+ * over `balances()` + `Array.find` — it fetches the FULL balances under the
1157
+ * hood (there is no server-side scoped read), so prefer `balances()` when you
1158
+ * need several rows from the same customer.
1159
+ */
1160
+ creditBalance(customerId: string, match: {
1161
+ creditId?: string;
1162
+ creditName?: string;
1163
+ }): Promise<CreditBalance | null>;
1164
+ /** One outcome balance for a customer, matched by `outcomeId` or
1165
+ * `outcomeName`; `null` when absent. See {@link creditBalance} for the
1166
+ * fetch-then-filter caveat. */
1167
+ outcomeBalance(customerId: string, match: {
1168
+ outcomeId?: string;
1169
+ outcomeName?: string;
1170
+ }): Promise<OutcomeBalance | null>;
1171
+ /** One unit balance for a customer, matched by `unitId` or `unitName`;
1172
+ * `null` when absent. See {@link creditBalance} for the fetch-then-filter
1173
+ * caveat. */
1174
+ unitBalance(customerId: string, match: {
1175
+ unitId?: string;
1176
+ unitName?: string;
1177
+ }): Promise<UnitBalance | null>;
895
1178
  /** The customer's current plan. `GET …/:id/plan`. */
896
1179
  plan(id: string): Promise<CustomerPlan>;
897
- /** Revenue / cost / profit / margin over a window. `GET …/:id/revenue`. */
898
- revenue(id: string, params?: {
899
- range?: RevenueRange;
900
- }): Promise<CustomerRevenue>;
901
1180
  /** List a customer's members. `GET …/:id/members`. */
902
1181
  listMembers(id: string): Promise<Member[]>;
903
1182
  /** Add a member to a customer. Duplicate `employeeId` → ConflictError. */
@@ -918,10 +1197,6 @@ declare class Customers {
918
1197
  transaction: WalletTransaction;
919
1198
  balanceUsd: number;
920
1199
  }>;
921
- /** Set the customer's currency. `PUT …/:id/currency`. */
922
- setCurrency(id: string, currencyCode: string): Promise<void>;
923
- /** Set which credit types the customer is billed against. `PUT …/:id/credits`. */
924
- setCreditTypes(id: string, creditIds: string[]): Promise<void>;
925
1200
  /** Grant or claw back a credit balance. `POST …/:id/credits/adjust`. */
926
1201
  adjustCredit(id: string, input: CreditAdjustInput): Promise<void>;
927
1202
  /** Grant or claw back an outcome balance. Returns the remaining balance. */
@@ -975,8 +1250,8 @@ declare class Outcomes {
975
1250
  get(id: string): Promise<OutcomeDetail>;
976
1251
  /** Update an outcome type's definition. `PATCH /api/v1/outcomes/:id`. */
977
1252
  update(id: string, input: UpdateOutcomeInput): Promise<Outcome>;
978
- /** Activate or deactivate an outcome type. */
979
- setActive(id: string, isActive: boolean): Promise<void>;
1253
+ /** Activate or deactivate an outcome type; returns the updated outcome. */
1254
+ setActive(id: string, isActive: boolean): Promise<Outcome>;
980
1255
  /** Delete an outcome type. */
981
1256
  delete(id: string): Promise<void>;
982
1257
  }
@@ -1122,6 +1397,12 @@ declare class Signals {
1122
1397
  track(signal: Signal, opts?: {
1123
1398
  wait?: boolean;
1124
1399
  }): Promise<TrackResult>;
1400
+ /**
1401
+ * Validate + price a signal WITHOUT recording it (server `dryRun`). Returns
1402
+ * the projected usage log so an integration can preflight before sending real
1403
+ * traffic — no inbox row, wallet / outcome writes, or webhooks fire.
1404
+ */
1405
+ verify(signal: Signal): Promise<SerializedUsageLog | null>;
1125
1406
  /** Meter a named credit. */
1126
1407
  credit(input: CreditInput, opts?: {
1127
1408
  wait?: boolean;
@@ -1140,12 +1421,12 @@ declare class Signals {
1140
1421
  limit?: number;
1141
1422
  }): Promise<UsageList>;
1142
1423
  /**
1143
- * Record one unit-metered event (a fixed-price meter with no tokens), matched
1144
- * to a catalog unit by name. Sent immediately — unit events are not buffered.
1145
- * `POST /api/v1/units`.
1424
+ * Record one unit-metered event (a fixed-price meter with no tokens),
1425
+ * addressed to a catalog unit by its `agentKey`. Sent immediately — unit
1426
+ * events are not buffered. `POST /api/v1/units`.
1146
1427
  */
1147
1428
  unit(input: UnitInput): Promise<{
1148
- unitUsage: Record<string, unknown>;
1429
+ unitUsage: SerializedUnitUsage;
1149
1430
  }>;
1150
1431
  /** A customer's unit balances + recent unit events. `GET /api/v1/units`. */
1151
1432
  unitUsage(params: {
@@ -1193,6 +1474,23 @@ declare class Webhooks {
1193
1474
  delete(kind: ThresholdKind): Promise<void>;
1194
1475
  }
1195
1476
 
1477
+ /**
1478
+ * The `workspace` resource — read-only introspection of the org behind the API
1479
+ * key. Grounds an integration (which workspace, and is it `sandbox` or `live`?)
1480
+ * and lists the models it may meter against. `/api/v1/me`, `/api/v1/models`.
1481
+ */
1482
+ declare class Workspace {
1483
+ private readonly transport;
1484
+ constructor(transport: Transport);
1485
+ /** Identify the org + key behind the request, incl. `sandbox` | `live`. */
1486
+ me(): Promise<WorkspaceIdentity>;
1487
+ /** The org's enabled models with live prices. `{ active: true }` returns only
1488
+ * the models that can be metered right now. */
1489
+ models(params?: {
1490
+ active?: boolean;
1491
+ }): Promise<Model[]>;
1492
+ }
1493
+
1196
1494
  /**
1197
1495
  * The ClockNext client.
1198
1496
  *
@@ -1233,6 +1531,8 @@ declare class ClockNext {
1233
1531
  readonly webhooks: Webhooks;
1234
1532
  /** Mint customer-portal embed tokens. */
1235
1533
  readonly portal: Portal;
1534
+ /** Identify the workspace (sandbox/live) + list its models. `/me`, `/models`. */
1535
+ readonly workspace: Workspace;
1236
1536
  private readonly cfg;
1237
1537
  private readonly flusher;
1238
1538
  constructor(config: ClockNextConfig);
@@ -1293,4 +1593,4 @@ declare class NetworkError extends ClockNextError {
1293
1593
  constructor(message: string);
1294
1594
  }
1295
1595
 
1296
- export { type AddMemberInput, AllowanceError, type ApiCustomer, AuthError, type BillingCycle, type BillingMode, ClockNext, type ClockNextConfig, ClockNextError, type ComponentType, ConflictError, type CreateCreditInput, type CreateCustomerInput, type CreateOutcomeInput, type CreatePlanInput, type CreatePurchaseInput, type CreateUnitInput, type Credit, type CreditAdjustInput, type CreditDetail, type CreditInput, type CreditSignal, type CustomerBalances, type CustomerList, type CustomerPlan, type CustomerProfileInput, type CustomerRevenue, type DropReason, type FetchLike, type Invoice, type InvoiceDetail, type InvoiceLineItem, type InvoiceListRow, type InvoiceParty, type InvoicePlanSnapshot, type InvoiceStatus, type Logger, type Member, type MemberRole, type ModelBundleEntry, NetworkError, NotFoundError, type Outcome, type OutcomeAdjustInput, type OutcomeDetail, type OutcomeInput, type OutcomeSignal, type OutcomeStepInput, type PayLink, type PaymentDetail, type PaymentRow, type Plan, type PlanComponent, type PlanComponentInput, type PlanDetail, PlanError, type PlanKind, type PlanRef, type PlanType, type PortalToken, type PortalTokenInput, type Purchase, type PurchaseDetail, type PurchaseStatus, RateLimitError, type RevenueRange, type SerializedOutcomeAttribution, type SerializedRuleApplication, type SerializedUsageLog, ServerError, type Signal, type SignalStatus, type SignalType, type ThresholdKind, type Tokens, type TrackResult, type Unit, type UnitAdjustInput, type UnitDetail, type UnitInput, type UnitPricingType, type UnitTier, type UnitTierInput, type UnitUsageList, type UnitUsageRow, type UpdateCreditInput, type UpdateMemberInput, type UpdateOutcomeInput, type UpdatePlanInput, type UpdateUnitInput, type UpsertWebhookInput, type UsageList, ValidationError, type WalletEntryInput, type WalletInput, type WalletList, type WalletSignal, type WalletTransaction, type WalletTransactionType, type Webhook, signalToWire };
1596
+ export { type AddMemberInput, AllowanceError, type ApiCustomer, AuthError, type BillingCycle, type BillingMode, ClockNext, type ClockNextConfig, ClockNextError, type ComponentType, ConflictError, type CostPoint, type CostStats, type CreateCreditInput, type CreateCustomerInput, type CreateOutcomeInput, type CreatePlanInput, type CreatePurchaseInput, type CreateUnitInput, type Credit, type CreditAdjustInput, type CreditAnalytics, type CreditBalance, type CreditComponentInput, type CreditDetail, type CreditInput, type CreditSignal, type CustomerBalances, type CustomerList, type CustomerPlan, type CustomerPlanDetails, type CustomerProfileInput, type DropReason, type FetchLike, type FlatComponentInput, type FlatUnitInput, type Invoice, type InvoiceDetail, type InvoiceLineItem, type InvoiceListRow, type InvoiceParty, type InvoicePlanSnapshot, type InvoiceStatus, type Logger, type Member, type MemberRole, type Model, type ModelBundleEntry, NetworkError, NotFoundError, type Outcome, type OutcomeAdjustInput, type OutcomeAnalytics, type OutcomeBalance, type OutcomeComponentInput, type OutcomeDetail, type OutcomeInput, type OutcomeSignal, type OutcomeStepInput, type PayLink, type PaymentDetail, type PaymentRow, type Plan, type PlanComponent, type PlanComponentInput, type PlanDetail, PlanError, type PlanKind, type PlanRef, type PlanType, type PortalToken, type PortalTokenInput, type Purchase, type PurchaseDetail, type PurchaseStatus, RateLimitError, type SerializedOutcomeAttribution, type SerializedRuleApplication, type SerializedUnitUsage, type SerializedUsageLog, ServerError, type Signal, type SignalStatus, type SignalType, type ThresholdKind, type TieredUnitInput, type Tokens, type TrackResult, type Unit, type UnitAdjustInput, type UnitBalance, type UnitComponentInput, type UnitCustomerRow, type UnitDetail, type UnitInput, type UnitPricingType, type UnitTier, type UnitTierInput, type UnitUsageList, type UnitUsageRow, type UpdateCreditInput, type UpdateMemberInput, type UpdateOutcomeInput, type UpdatePlanInput, type UpdateUnitInput, type UpsertWebhookInput, type UsageBalance, type UsageList, ValidationError, type WalletComponentInput, type WalletEntryInput, type WalletInput, type WalletList, type WalletSignal, type WalletTransaction, type WalletTransactionType, type Webhook, type WorkspaceIdentity, signalToWire };