@clocknext/sdk 0.14.0 → 0.16.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 +274 -128
- package/dist/index.cjs +345 -281
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +689 -773
- package/dist/index.d.ts +689 -773
- package/dist/index.js +345 -281
- package/dist/index.js.map +1 -1
- package/examples/node-basic.ts +24 -32
- package/package.json +1 -1
- package/src/client.ts +15 -23
- package/src/customer-ref.ts +14 -0
- package/src/errors.ts +10 -2
- package/src/filters.ts +1 -1
- package/src/index.ts +32 -58
- package/src/resources/composites.ts +55 -20
- package/src/resources/credits.ts +40 -35
- package/src/resources/customers.ts +201 -82
- package/src/resources/invoices.ts +1 -1
- package/src/resources/outcomes.ts +40 -41
- package/src/resources/plans.ts +38 -32
- package/src/resources/signals.ts +8 -46
- package/src/resources/units.ts +37 -37
- package/src/types.ts +549 -619
- package/src/resources/webhooks.ts +0 -37
- package/src/resources/workspace.ts +0 -33
package/src/types.ts
CHANGED
|
@@ -21,12 +21,15 @@ export type SignalStatus = "SUCCESS" | "FAILURE" | "PENDING";
|
|
|
21
21
|
/**
|
|
22
22
|
* Token counts for a signal. `input` and `output` are required — every metered
|
|
23
23
|
* call has them, and the server requires them. `cache` (provider-specific
|
|
24
|
-
* prompt-cache reads)
|
|
24
|
+
* prompt-cache reads) and `cacheWrite` (tokens written into the prompt cache,
|
|
25
|
+
* priced at the model's separate cache-write rate) are optional and default to
|
|
26
|
+
* 0 server-side when omitted.
|
|
25
27
|
*/
|
|
26
28
|
export interface Tokens {
|
|
27
29
|
input: number;
|
|
28
30
|
output: number;
|
|
29
31
|
cache?: number;
|
|
32
|
+
cacheWrite?: number;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
/**
|
|
@@ -65,42 +68,40 @@ export interface CompositeTag {
|
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
// ---------------------------------------------------------------------------
|
|
68
|
-
//
|
|
71
|
+
// Naming a customer
|
|
69
72
|
// ---------------------------------------------------------------------------
|
|
70
73
|
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
74
|
+
/**
|
|
75
|
+
* How a request names its customer: by OUR id (`customerId`) or by YOUR id for
|
|
76
|
+
* them (`externalId` — the value set on the customer via
|
|
77
|
+
* `customers.create()` / `customers.update()`). At least one is required.
|
|
78
|
+
*
|
|
79
|
+
* When both are sent, `customerId` wins and `externalId` is ignored — the
|
|
80
|
+
* server does not check that they agree. An `externalId` matching no active
|
|
81
|
+
* customer is a `NotFoundError` (or, on an async signal, leaves it Pending
|
|
82
|
+
* with that reason — retry once the customer exists).
|
|
83
|
+
*/
|
|
84
|
+
export type CustomerRef =
|
|
85
|
+
| {
|
|
86
|
+
/** Our customer id. Wins over `externalId` when both are sent. */
|
|
87
|
+
customerId: string;
|
|
88
|
+
externalId?: string;
|
|
89
|
+
}
|
|
90
|
+
| {
|
|
91
|
+
customerId?: undefined;
|
|
92
|
+
/** Your id for the customer: 1–32 letters, numbers or "-", matched
|
|
93
|
+
* exactly (case-sensitive). */
|
|
94
|
+
externalId: string;
|
|
95
|
+
};
|
|
87
96
|
|
|
88
|
-
/**
|
|
89
|
-
*
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
provider: string;
|
|
94
|
-
providerName: string;
|
|
95
|
-
isActive: boolean;
|
|
96
|
-
inputPrice: number;
|
|
97
|
-
outputPrice: number;
|
|
98
|
-
cachePrice: number;
|
|
99
|
-
}
|
|
97
|
+
/** `Omit` that keeps a union a union (plain `Omit` flattens it to the
|
|
98
|
+
* members' shared keys, losing the {@link CustomerRef} either/or). */
|
|
99
|
+
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown
|
|
100
|
+
? Omit<T, K>
|
|
101
|
+
: never;
|
|
100
102
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
customerId: string;
|
|
103
|
+
/** Every signal names its customer — see {@link CustomerRef}. */
|
|
104
|
+
interface SignalFields {
|
|
104
105
|
/**
|
|
105
106
|
* The model's catalog id — must be enabled in your ClockNext org
|
|
106
107
|
* (Settings → Models). Matched case-insensitively against `OrgModel.modelId`.
|
|
@@ -123,19 +124,21 @@ interface SignalBase {
|
|
|
123
124
|
idempotencyKey?: string;
|
|
124
125
|
}
|
|
125
126
|
|
|
127
|
+
type SignalBase = CustomerRef & SignalFields;
|
|
128
|
+
|
|
126
129
|
/** Meters a credit, identified by the credit's stable `agentKey`. */
|
|
127
|
-
export
|
|
130
|
+
export type CreditSignal = SignalBase & {
|
|
128
131
|
type: "credit";
|
|
129
132
|
/** The Credit's stable agent key (assigned when the credit was created). */
|
|
130
133
|
agentKey: string;
|
|
131
134
|
/** Optional composite this signal belongs to. See {@link CompositeTag}. */
|
|
132
135
|
composite?: CompositeTag;
|
|
133
|
-
}
|
|
136
|
+
};
|
|
134
137
|
|
|
135
138
|
/** Debits the customer's wallet in USD at the model's cost. */
|
|
136
|
-
export
|
|
139
|
+
export type WalletSignal = SignalBase & {
|
|
137
140
|
type: "wallet";
|
|
138
|
-
}
|
|
141
|
+
};
|
|
139
142
|
|
|
140
143
|
/**
|
|
141
144
|
* Records one step of a multi-call outcome run. The `agentKey` identifies the
|
|
@@ -149,7 +152,7 @@ export interface WalletSignal extends SignalBase {
|
|
|
149
152
|
* carries `complete` — see {@link OutcomeCompletionInput} /
|
|
150
153
|
* `signals.completeOutcome()`, its own dedicated route.
|
|
151
154
|
*/
|
|
152
|
-
export
|
|
155
|
+
export type OutcomeSignal = SignalBase & {
|
|
153
156
|
type: "outcome";
|
|
154
157
|
/** The OutcomeStep's stable agent key — identifies the outcome AND the step. */
|
|
155
158
|
agentKey: string;
|
|
@@ -161,14 +164,14 @@ export interface OutcomeSignal extends SignalBase {
|
|
|
161
164
|
runId: string;
|
|
162
165
|
/** Optional composite this signal belongs to. See {@link CompositeTag}. */
|
|
163
166
|
composite?: CompositeTag;
|
|
164
|
-
}
|
|
167
|
+
};
|
|
165
168
|
|
|
166
169
|
export type Signal = CreditSignal | WalletSignal | OutcomeSignal;
|
|
167
170
|
|
|
168
171
|
/** Helper input shapes for the per-type convenience methods. */
|
|
169
|
-
export type CreditInput =
|
|
170
|
-
export type WalletInput =
|
|
171
|
-
export type OutcomeInput =
|
|
172
|
+
export type CreditInput = DistributiveOmit<CreditSignal, "type">;
|
|
173
|
+
export type WalletInput = DistributiveOmit<WalletSignal, "type">;
|
|
174
|
+
export type OutcomeInput = DistributiveOmit<OutcomeSignal, "type">;
|
|
172
175
|
|
|
173
176
|
/**
|
|
174
177
|
* Input for `signals.completeOutcome()` — closes ONE outcome run, the outcome
|
|
@@ -181,17 +184,17 @@ export type OutcomeInput = Omit<OutcomeSignal, "type">;
|
|
|
181
184
|
* `signals.completeComposite()` — the two completions are independent, and
|
|
182
185
|
* neither implies the other.
|
|
183
186
|
*/
|
|
184
|
-
export
|
|
185
|
-
customerId: string;
|
|
187
|
+
export type OutcomeCompletionInput = CustomerRef & {
|
|
186
188
|
/** The same `runId` the run's step signals were sent with. */
|
|
187
189
|
runId: string;
|
|
188
190
|
/** Optional member (email) this completion is attributed to. */
|
|
189
191
|
member?: string;
|
|
190
|
-
/** Idempotency key, auto-generated if omitted. Sending
|
|
191
|
-
* the same run is already a safe no-op server-side, so this only
|
|
192
|
-
* a retry into one attempt rather than protecting against a
|
|
192
|
+
/** Idempotency key, auto-generated if omitted. Sending this completion twice
|
|
193
|
+
* for the same run is already a safe no-op server-side, so this only
|
|
194
|
+
* collapses a retry into one attempt rather than protecting against a
|
|
195
|
+
* double bill. */
|
|
193
196
|
idempotencyKey?: string;
|
|
194
|
-
}
|
|
197
|
+
};
|
|
195
198
|
|
|
196
199
|
/**
|
|
197
200
|
* The result of `signals.completeOutcome()`.
|
|
@@ -273,7 +276,10 @@ export interface SerializedUsageLog {
|
|
|
273
276
|
member: string | null;
|
|
274
277
|
inputTokens: number;
|
|
275
278
|
outputTokens: number;
|
|
279
|
+
/** Cache-read tokens. */
|
|
276
280
|
cacheTokens: number;
|
|
281
|
+
/** Cache-write tokens, priced separately from cache reads. */
|
|
282
|
+
cacheWriteTokens: number;
|
|
277
283
|
/** Total credits deducted: the call's real per-model provider cost as a
|
|
278
284
|
* fraction of the credit's base price (i.e. cost + your margin), plus any
|
|
279
285
|
* credit-rule add-ons; 0 for wallet-money calls. */
|
|
@@ -304,7 +310,7 @@ export interface SerializedUsageLog {
|
|
|
304
310
|
* exhausted allowance is detected by the worker LATER and never surfaces here —
|
|
305
311
|
* the signal is simply dropped. A `202` therefore means "accepted", never
|
|
306
312
|
* "recorded". To confirm a signal actually landed, read it back with
|
|
307
|
-
* `signals.
|
|
313
|
+
* `signals.usageLog({ customerId })`.
|
|
308
314
|
*
|
|
309
315
|
* When the server has no queue configured it prices inline instead and returns
|
|
310
316
|
* `queued: false` with a populated `usageLog`, validating synchronously.
|
|
@@ -327,7 +333,7 @@ export interface TrackResult {
|
|
|
327
333
|
* and will price it shortly. It can no longer be lost, but
|
|
328
334
|
* it is not billed yet and `usageLog` is null. A rejection
|
|
329
335
|
* discovered during pricing will NOT come back to you here,
|
|
330
|
-
* nor on `onError`. `signals.
|
|
336
|
+
* nor on `onError`. `signals.usageLog()` shows what got priced;
|
|
331
337
|
* the dashboard's signal log — owner-only, by design — is
|
|
332
338
|
* where an individual rejection says why.
|
|
333
339
|
* `"recorded"` — the server priced it inline and `usageLog` is populated.
|
|
@@ -373,18 +379,6 @@ export interface TrackResult {
|
|
|
373
379
|
rawId?: string;
|
|
374
380
|
}
|
|
375
381
|
|
|
376
|
-
export interface UsageList {
|
|
377
|
-
customer: { id: string; name: string; creditAllowance: number };
|
|
378
|
-
totals: {
|
|
379
|
-
count: number;
|
|
380
|
-
cost: number;
|
|
381
|
-
revenue: number;
|
|
382
|
-
profit: number;
|
|
383
|
-
creditsUsed: number;
|
|
384
|
-
};
|
|
385
|
-
logs: SerializedUsageLog[];
|
|
386
|
-
}
|
|
387
|
-
|
|
388
382
|
// ---------------------------------------------------------------------------
|
|
389
383
|
// Usage log (mirrors GET /api/v1/signal/usage-log)
|
|
390
384
|
// ---------------------------------------------------------------------------
|
|
@@ -443,7 +437,14 @@ export interface UsageLogEntry {
|
|
|
443
437
|
typeName: string | null;
|
|
444
438
|
member: string | null;
|
|
445
439
|
model: { name: string | null; provider: string | null } | null;
|
|
446
|
-
usage: {
|
|
440
|
+
usage: {
|
|
441
|
+
inputTokens: number;
|
|
442
|
+
outputTokens: number;
|
|
443
|
+
/** Cache-read tokens. */
|
|
444
|
+
cacheTokens: number;
|
|
445
|
+
/** Cache-write tokens, priced separately from cache reads. */
|
|
446
|
+
cacheWriteTokens: number;
|
|
447
|
+
};
|
|
447
448
|
/** Formatted USD strings (e.g. `"$0.0064"`). */
|
|
448
449
|
cost: { providedCost: string; customerCost: string };
|
|
449
450
|
/** Populated only when `kind === "credit"`. `amount` is a formatted credit
|
|
@@ -471,6 +472,9 @@ export interface UsageLogPage {
|
|
|
471
472
|
|
|
472
473
|
export interface ApiCustomer {
|
|
473
474
|
id: string;
|
|
475
|
+
/** Your own id for this customer, or `null` when unset. See
|
|
476
|
+
* {@link CustomerProfileInput.externalId}. */
|
|
477
|
+
externalId: string | null;
|
|
474
478
|
slug: string;
|
|
475
479
|
name: string;
|
|
476
480
|
description: string | null;
|
|
@@ -486,12 +490,24 @@ export interface ApiCustomer {
|
|
|
486
490
|
taxId: string | null;
|
|
487
491
|
currencyCode: string;
|
|
488
492
|
creditAllowance: number;
|
|
493
|
+
recurringTransactionEmail: boolean;
|
|
494
|
+
autoRecurring: boolean;
|
|
489
495
|
createdAt: string;
|
|
490
496
|
updatedAt: string;
|
|
491
497
|
}
|
|
492
498
|
|
|
493
499
|
/** Writable customer profile fields. `null` clears a column; omit to leave it. */
|
|
494
500
|
export interface CustomerProfileInput {
|
|
501
|
+
/**
|
|
502
|
+
* The id YOUR product uses for this customer: 1–32 letters, numbers or "-",
|
|
503
|
+
* case-sensitive. Unique among the org's active customers (a clash is a
|
|
504
|
+
* `ConflictError`; an archived customer's id can be reused). Once set,
|
|
505
|
+
* signals and `purchases.create()` can take `externalId` instead of
|
|
506
|
+
* `customerId`, and `customers.getByExternalId()` / `updateByExternalId()` /
|
|
507
|
+
* `updateRecurringGrantByExternalId()` address the customer by it. `null`
|
|
508
|
+
* clears it on update.
|
|
509
|
+
*/
|
|
510
|
+
externalId?: string | null;
|
|
495
511
|
name?: string;
|
|
496
512
|
description?: string | null;
|
|
497
513
|
email?: string | null;
|
|
@@ -506,6 +522,10 @@ export interface CustomerProfileInput {
|
|
|
506
522
|
taxId?: string | null;
|
|
507
523
|
/** ISO 4217 (3 letters); must be enabled for the org. */
|
|
508
524
|
currencyCode?: string;
|
|
525
|
+
/** Send the invoice, payment receipt and card-payment-failed emails for recurring invoices. Defaults to `true` on create. */
|
|
526
|
+
recurringTransactionEmail?: boolean;
|
|
527
|
+
/** Issue every recurring invoice as `AUTO_CLOSED` (applied as if paid, never payable). Defaults to `false` on create. */
|
|
528
|
+
autoRecurring?: boolean;
|
|
509
529
|
}
|
|
510
530
|
|
|
511
531
|
/** `name` and `email` are required on create; every other field is optional. */
|
|
@@ -541,7 +561,7 @@ export interface OutcomeBalance {
|
|
|
541
561
|
remaining: number;
|
|
542
562
|
/** Each step's `agentKey` is what `signals.outcome()` and the outcome adjust
|
|
543
563
|
* API use to address this outcome at runtime. The outcome also has its own
|
|
544
|
-
* separate key (
|
|
564
|
+
* separate key (the outcome's own `agentKey`), but neither of those APIs accepts
|
|
545
565
|
* it — it identifies the outcome in the catalogue, not in a signal. */
|
|
546
566
|
steps: { id: string; name: string; agentKey: string }[];
|
|
547
567
|
}
|
|
@@ -557,16 +577,45 @@ export interface UnitBalance {
|
|
|
557
577
|
remaining: number;
|
|
558
578
|
}
|
|
559
579
|
|
|
560
|
-
/**
|
|
561
|
-
|
|
580
|
+
/** One prepaid (ADVANCE) composite pool on a customer's plan. */
|
|
581
|
+
export interface CompositeBalance {
|
|
582
|
+
compositeId: string;
|
|
583
|
+
/** The tag signals send in their `composite` block. */
|
|
584
|
+
refId: string;
|
|
585
|
+
name: string;
|
|
586
|
+
/** The pool size the plan grants this cycle. */
|
|
587
|
+
granted: number;
|
|
588
|
+
/** Slots claimed this cycle — one per distinct tag value. */
|
|
589
|
+
used: number;
|
|
590
|
+
/** `granted - used` plus this cycle's manual adjustments. May be negative:
|
|
591
|
+
* running past the pool is allowed and carries into the next cycle. */
|
|
592
|
+
remaining: number;
|
|
593
|
+
/** What `granted` was before the pool was ever resized for this customer;
|
|
594
|
+
* `null` if it never was. */
|
|
595
|
+
originalGranted: number | null;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/** Wallet / credit / outcome / unit balances and composite pools for a
|
|
599
|
+
* customer's active plan (`customers.balances()`). */
|
|
562
600
|
export interface CustomerBalances {
|
|
563
601
|
customerId: string;
|
|
564
602
|
currency: { code: string; rateUsd: number };
|
|
565
603
|
hasPlan: boolean;
|
|
566
|
-
wallet
|
|
604
|
+
/** Both wallet balances, in USD. Always present. */
|
|
605
|
+
wallet: {
|
|
606
|
+
/** The ordinary wallet — always reported, also when the plan has no
|
|
607
|
+
* Wallet component or there's no plan. May be negative. */
|
|
608
|
+
balance: number;
|
|
609
|
+
/** The Reserved Wallet; absent when the org hasn't enabled it, otherwise
|
|
610
|
+
* present whether or not the plan has a Wallet. Never negative. */
|
|
611
|
+
reservedBalance?: number;
|
|
612
|
+
};
|
|
567
613
|
credits: CreditBalance[];
|
|
568
614
|
outcomes: OutcomeBalance[];
|
|
569
615
|
units: UnitBalance[];
|
|
616
|
+
/** ADVANCE composite pools. A composite billed in ARREAR has no pool and
|
|
617
|
+
* isn't listed. */
|
|
618
|
+
composites: CompositeBalance[];
|
|
570
619
|
}
|
|
571
620
|
|
|
572
621
|
/** The customer's active plan (the `plan` field of `customers.plan()`);
|
|
@@ -615,17 +664,15 @@ export interface PortalToken {
|
|
|
615
664
|
// Plans
|
|
616
665
|
// ---------------------------------------------------------------------------
|
|
617
666
|
|
|
618
|
-
/** How often a plan bills. `FREE` is a one-time grant
|
|
667
|
+
/** How often a plan bills. `FREE` is a one-time grant. */
|
|
619
668
|
export type BillingCycle =
|
|
620
669
|
| "MONTHLY"
|
|
621
670
|
| "QUARTERLY"
|
|
622
671
|
| "SEMI_ANNUAL"
|
|
623
672
|
| "YEARLY"
|
|
624
|
-
| "EVERY_5_MIN"
|
|
625
673
|
| "FREE";
|
|
626
674
|
export type PlanType = "WALLET" | "BUNDLE";
|
|
627
675
|
export type PlanKind = "FLAT_PRICE" | "PAY_AS_YOU_GO" | "PAY_PER_SEAT";
|
|
628
|
-
/** A plan component's meter type. */
|
|
629
676
|
/**
|
|
630
677
|
* A plan component's kind.
|
|
631
678
|
*
|
|
@@ -644,132 +691,33 @@ export type ComponentType =
|
|
|
644
691
|
/** ADVANCE bills up-front for the cycle; ARREAR bills for what was consumed. */
|
|
645
692
|
export type BillingMode = "ADVANCE" | "ARREAR";
|
|
646
693
|
|
|
647
|
-
/**
|
|
648
|
-
|
|
649
|
-
export interface WalletComponentInput {
|
|
650
|
-
type: "WALLET";
|
|
651
|
-
billingMode: BillingMode;
|
|
652
|
-
amount: number;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
/** A one-off flat fee — `amount` is required. Max one flat component per plan;
|
|
656
|
-
* not allowed on FREE plans. */
|
|
657
|
-
export interface FlatComponentInput {
|
|
658
|
-
type: "FLAT";
|
|
659
|
-
billingMode: BillingMode;
|
|
660
|
-
amount: number;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
/** A credit entitlement, referenced by `creditId`. Billed ADVANCE it needs a
|
|
664
|
-
* granted `quantity`; billed ARREAR it meters usage with no upfront grant. */
|
|
665
|
-
export type CreditComponentInput =
|
|
666
|
-
| { type: "CREDIT"; billingMode: "ADVANCE"; creditId: string; quantity: number }
|
|
667
|
-
| { type: "CREDIT"; billingMode: "ARREAR"; creditId: string; quantity?: number | null };
|
|
668
|
-
|
|
669
|
-
/** An outcome entitlement, referenced by `outcomeId`. ADVANCE needs a granted
|
|
670
|
-
* `quantity`; ARREAR meters usage. */
|
|
671
|
-
export type OutcomeComponentInput =
|
|
672
|
-
| { type: "OUTCOME"; billingMode: "ADVANCE"; outcomeId: string; quantity: number }
|
|
673
|
-
| { type: "OUTCOME"; billingMode: "ARREAR"; outcomeId: string; quantity?: number | null };
|
|
674
|
-
|
|
675
|
-
/** A unit entitlement, referenced by `unitId`. ADVANCE needs a granted
|
|
676
|
-
* `quantity`; ARREAR meters usage. */
|
|
677
|
-
export type UnitComponentInput =
|
|
678
|
-
| { type: "UNIT"; billingMode: "ADVANCE"; unitId: string; quantity: number }
|
|
679
|
-
| { type: "UNIT"; billingMode: "ARREAR"; unitId: string; quantity?: number | null };
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* A COMPOSITE sold on the plan, referenced by `pricingMetricId` (the id from
|
|
683
|
-
* `composites.list()`). This is the line that makes a composite bill: the
|
|
684
|
-
* catalogue entry on its own charges nobody, and this component is what turns
|
|
685
|
-
* it into money — `quantity × the composite's price`, frozen into the purchase
|
|
686
|
-
* snapshot at buy time.
|
|
687
|
-
*
|
|
688
|
-
* The two billing modes differ in what `quantity` means:
|
|
689
|
-
* - **ADVANCE** — a PREPAID POOL of `quantity` flat-rate slots, shared
|
|
690
|
-
* across whichever credits / outcomes / units the composite wraps. Each
|
|
691
|
-
* distinct tag value claims one slot on completion; repeat signals under a
|
|
692
|
-
* value reuse the slot they already claimed, at no extra cost. Once every
|
|
693
|
-
* slot is claimed, further occurrences are refused rather than billed.
|
|
694
|
-
* - **ARREAR** — nothing prepaid; completed occurrences are counted on the
|
|
695
|
-
* cycle-end line.
|
|
696
|
-
*
|
|
697
|
-
* `type` is the wire value `"PRICING_METRIC"`, not `"COMPOSITE"`: the product
|
|
698
|
-
* word changed but the stored enum did not, and the API still speaks the old
|
|
699
|
-
* one. That mismatch is the server's, and it is surfaced rather than hidden so
|
|
700
|
-
* a response and a request read the same.
|
|
701
|
-
*/
|
|
702
|
-
export type CompositeComponentInput =
|
|
703
|
-
| {
|
|
704
|
-
type: "PRICING_METRIC";
|
|
705
|
-
billingMode: "ADVANCE";
|
|
706
|
-
pricingMetricId: string;
|
|
707
|
-
quantity: number;
|
|
708
|
-
}
|
|
709
|
-
| {
|
|
710
|
-
type: "PRICING_METRIC";
|
|
711
|
-
billingMode: "ARREAR";
|
|
712
|
-
pricingMetricId: string;
|
|
713
|
-
quantity?: number | null;
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
/**
|
|
717
|
-
* One entitlement line in a plan — a discriminated union on `type` (and, where
|
|
718
|
-
* it matters, `billingMode`) so the per-type fields the server requires are
|
|
719
|
-
* enforced at compile time instead of surfacing as runtime 422s:
|
|
720
|
-
* - CREDIT / OUTCOME / UNIT require their matching id;
|
|
721
|
-
* - PRICING_METRIC (a composite) requires `pricingMetricId`;
|
|
722
|
-
* - CREDIT / OUTCOME / UNIT / PRICING_METRIC require `quantity` when billed
|
|
723
|
-
* ADVANCE;
|
|
724
|
-
* - WALLET / FLAT require `amount`.
|
|
725
|
-
*/
|
|
726
|
-
export type PlanComponentInput =
|
|
727
|
-
| WalletComponentInput
|
|
728
|
-
| FlatComponentInput
|
|
729
|
-
| CreditComponentInput
|
|
730
|
-
| OutcomeComponentInput
|
|
731
|
-
| UnitComponentInput
|
|
732
|
-
| CompositeComponentInput;
|
|
733
|
-
|
|
734
|
-
export interface CreatePlanInput {
|
|
735
|
-
name: string;
|
|
736
|
-
description?: string | null;
|
|
737
|
-
billingCycle: BillingCycle;
|
|
738
|
-
/** Carry an unused balance into the next cycle. Default true. */
|
|
739
|
-
carryForward?: boolean;
|
|
740
|
-
/** ISO 4217 (3 letters). Default "USD". */
|
|
741
|
-
currencyCode?: string;
|
|
742
|
-
isActive?: boolean;
|
|
743
|
-
/** At least one component. FREE plans must be ADVANCE-only with no FLAT component. */
|
|
744
|
-
components: PlanComponentInput[];
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
/** A full-rewrite update carries the complete plan (same shape as create). */
|
|
748
|
-
export type UpdatePlanInput = CreatePlanInput;
|
|
749
|
-
|
|
750
|
-
export interface PlanComponent {
|
|
694
|
+
/** One line of a plan (`plan.entitlements[]`). */
|
|
695
|
+
export interface PlanEntitlement {
|
|
751
696
|
id: string;
|
|
752
697
|
type: ComponentType;
|
|
753
698
|
billingMode: BillingMode;
|
|
754
699
|
creditId: string | null;
|
|
755
700
|
outcomeId: string | null;
|
|
756
701
|
unitId: string | null;
|
|
757
|
-
/** The composite this component sells, on a `PRICING_METRIC`
|
|
758
|
-
*
|
|
759
|
-
|
|
760
|
-
* silently dropped every composite component. */
|
|
761
|
-
pricingMetricId: string | null;
|
|
702
|
+
/** The id of the composite this component sells, on a `PRICING_METRIC`
|
|
703
|
+
* component. */
|
|
704
|
+
compositeId: string | null;
|
|
762
705
|
targetName: string | null;
|
|
763
706
|
quantity: number | null;
|
|
764
707
|
amount: number | null;
|
|
708
|
+
/** ADVANCE credit / outcome / composite / wallet components: what's left at
|
|
709
|
+
* the end of a cycle carries into the next one instead of resetting.
|
|
710
|
+
* Always false for unit, flat and ARREAR components and on FREE plans. */
|
|
711
|
+
rollover: boolean;
|
|
765
712
|
}
|
|
766
713
|
|
|
714
|
+
/** @deprecated Renamed to {@link PlanEntitlement} — a plan's lines are `entitlements` now. */
|
|
715
|
+
export type PlanComponent = PlanEntitlement;
|
|
716
|
+
|
|
767
717
|
export interface Plan {
|
|
768
718
|
id: string;
|
|
769
719
|
name: string;
|
|
770
720
|
description: string | null;
|
|
771
|
-
type: PlanType;
|
|
772
|
-
kind: PlanKind;
|
|
773
721
|
billingCycle: BillingCycle;
|
|
774
722
|
cost: number;
|
|
775
723
|
/** Signed adjustment applied to the plan's headline price (default 0). */
|
|
@@ -777,29 +725,292 @@ export interface Plan {
|
|
|
777
725
|
/** When true, ARREAR consumption is funded from the customer's wallet as it
|
|
778
726
|
* happens instead of being invoiced at cycle end. All-or-nothing per plan. */
|
|
779
727
|
walletFundedArrear: boolean;
|
|
728
|
+
/** The workspace's primary currency when the plan was created. */
|
|
780
729
|
currencyCode: string;
|
|
781
730
|
isActive: boolean;
|
|
782
|
-
|
|
731
|
+
createdAt: string;
|
|
732
|
+
updatedAt: string;
|
|
733
|
+
/** The plan's lines — what a customer on it is granted or metered for. */
|
|
734
|
+
entitlements: PlanEntitlement[];
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/** One line of a plan, as you send it to `plans.create()` / `plans.update()`.
|
|
738
|
+
* Set the id that matches `type`: `creditId` (CREDIT), `outcomeId`
|
|
739
|
+
* (OUTCOME), `unitId` (UNIT) or `compositeId` (PRICING_METRIC — a
|
|
740
|
+
* composite). The lines `plans.get()` returns can be sent back as they are. */
|
|
741
|
+
export interface PlanEntitlementInput {
|
|
742
|
+
type: ComponentType;
|
|
743
|
+
billingMode: BillingMode;
|
|
744
|
+
creditId?: string | null;
|
|
745
|
+
outcomeId?: string | null;
|
|
746
|
+
unitId?: string | null;
|
|
747
|
+
compositeId?: string | null;
|
|
748
|
+
/** ADVANCE credit / outcome / unit / composite: granted each cycle (0 allowed). */
|
|
749
|
+
quantity?: number | null;
|
|
750
|
+
/** WALLET (ADVANCE prepaid balance, $0 allowed) or FLAT (fee, above $0), in USD. */
|
|
751
|
+
amount?: number | null;
|
|
752
|
+
/** ADVANCE credit / outcome / composite / wallet: carry leftovers into the next cycle. */
|
|
753
|
+
rollover?: boolean;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/** `plans.create()` body. The plan's currency is the workspace's primary
|
|
757
|
+
* currency — it can't be chosen. A new plan is active; retire it with
|
|
758
|
+
* `plans.archive()`. */
|
|
759
|
+
export interface CreatePlanInput {
|
|
760
|
+
name: string;
|
|
761
|
+
billingCycle: BillingCycle;
|
|
762
|
+
description?: string | null;
|
|
763
|
+
/** Pay ARREAR usage from the prepaid wallet as it happens. Needs an ADVANCE
|
|
764
|
+
* WALLET line and at least one ARREAR credit / outcome / unit / composite. */
|
|
765
|
+
walletFundedArrear?: boolean;
|
|
766
|
+
/** Signed rounding nudge (USD) on the due-at-purchase total. */
|
|
767
|
+
priceAdjustment?: number;
|
|
768
|
+
/** At least one line. At most one WALLET and one FLAT. */
|
|
769
|
+
entitlements: PlanEntitlementInput[];
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/** `plans.update()` body — a PARTIAL update: only the fields you send change.
|
|
773
|
+
* `entitlements`, when sent, is the complete new list. */
|
|
774
|
+
export type UpdatePlanInput = Partial<CreatePlanInput>;
|
|
775
|
+
|
|
776
|
+
// ---------------------------------------------------------------------------
|
|
777
|
+
// Catalogue: credits, outcomes, units, composites
|
|
778
|
+
//
|
|
779
|
+
// Every catalogue resource has the same six calls — list, get, create,
|
|
780
|
+
// update (a PARTIAL update: only the fields you send change), archive and
|
|
781
|
+
// unarchive — and NO delete: the API never deletes catalogue items, so usage
|
|
782
|
+
// history never loses what it points at. Archiving is the only way to retire
|
|
783
|
+
// one, and `isActive` is read-only.
|
|
784
|
+
// ---------------------------------------------------------------------------
|
|
785
|
+
|
|
786
|
+
/** One model line of a credit's / outcome step's pricing bundle, as returned. */
|
|
787
|
+
export interface ModelBundleLine {
|
|
788
|
+
/** The workspace's model row id (`id` from the Models API). */
|
|
789
|
+
orgModelId: string;
|
|
790
|
+
/** The model's display name, filled in by the server. */
|
|
791
|
+
modelName: string;
|
|
792
|
+
/** Average tokens one LLM call uses on this model. */
|
|
793
|
+
averageTokensPerLLMCall: number;
|
|
794
|
+
/** Whole-percent split of those tokens; the four add up to 100. */
|
|
795
|
+
input: number;
|
|
796
|
+
output: number;
|
|
797
|
+
cache: number;
|
|
798
|
+
/** 0 on a model with no cache-write price. */
|
|
799
|
+
cacheWrite: number;
|
|
783
800
|
}
|
|
784
801
|
|
|
785
|
-
/**
|
|
786
|
-
|
|
802
|
+
/** One model line as you send it. Several lines (one per model) are allowed;
|
|
803
|
+
* the price is the sum of their costs, worked out on the server from the
|
|
804
|
+
* models' live prices. */
|
|
805
|
+
export interface ModelBundleLineInput {
|
|
806
|
+
orgModelId: string;
|
|
807
|
+
/** Above 0. */
|
|
808
|
+
averageTokensPerLLMCall: number;
|
|
809
|
+
input: number;
|
|
810
|
+
output: number;
|
|
811
|
+
cache: number;
|
|
812
|
+
/** Default 0. Only on a model that has a cache-write price. */
|
|
813
|
+
cacheWrite?: number;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/** A credit — a token-metered entitlement your product draws down by its
|
|
817
|
+
* `agentKey`. */
|
|
818
|
+
export interface Credit {
|
|
819
|
+
id: string;
|
|
820
|
+
name: string;
|
|
821
|
+
/** What a credit signal names; unique in the workspace. */
|
|
822
|
+
agentKey: string;
|
|
823
|
+
description: string | null;
|
|
824
|
+
/** Sum of the bundle lines' tokens (display figure). */
|
|
825
|
+
tokensPerCredit: number;
|
|
826
|
+
/** Cost of one credit, worked out from `modelBundle`. */
|
|
827
|
+
basePrice: number;
|
|
828
|
+
modelBundle: ModelBundleLine[];
|
|
829
|
+
marginPercent: number;
|
|
830
|
+
/** `basePrice` plus the margin — what a customer pays per credit. */
|
|
831
|
+
pricePerCredit: number;
|
|
832
|
+
isActive: boolean;
|
|
787
833
|
createdAt: string;
|
|
834
|
+
updatedAt: string;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/** `credits.create()` body. The price is always worked out on the server from
|
|
838
|
+
* `modelBundle` — it is never typed in. */
|
|
839
|
+
export interface CreateCreditInput {
|
|
840
|
+
name: string;
|
|
841
|
+
agentKey: string;
|
|
842
|
+
/** -100 or more. */
|
|
843
|
+
marginPercent: number;
|
|
844
|
+
/** At least one line. */
|
|
845
|
+
modelBundle: ModelBundleLineInput[];
|
|
846
|
+
description?: string | null;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** `credits.update()` body — PARTIAL. Send `modelBundle` to re-price; leave it
|
|
850
|
+
* out to keep the stored base price (a new margin is applied on top). */
|
|
851
|
+
export type UpdateCreditInput = Partial<CreateCreditInput>;
|
|
852
|
+
|
|
853
|
+
/** An outcome — a multi-step deliverable billed per completed outcome. */
|
|
854
|
+
export interface Outcome {
|
|
855
|
+
id: string;
|
|
856
|
+
name: string;
|
|
857
|
+
/** The outcome's own key (unique in the workspace) — not what a step signal
|
|
858
|
+
* names; each step has its own `agentKey`. */
|
|
859
|
+
agentKey: string;
|
|
860
|
+
description: string | null;
|
|
861
|
+
isActive: boolean;
|
|
862
|
+
/** Sum of the steps' base prices. */
|
|
863
|
+
basePrice: number;
|
|
864
|
+
marginPercent: number;
|
|
865
|
+
pricePerOutcome: number;
|
|
866
|
+
createdAt: string;
|
|
867
|
+
updatedAt: string;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/** One step of an outcome. */
|
|
871
|
+
export interface OutcomeStep {
|
|
872
|
+
/** Send it back on `outcomes.update()` to keep this step. */
|
|
873
|
+
id: string;
|
|
874
|
+
name: string;
|
|
875
|
+
/** What an outcome step signal names; unique in the workspace. */
|
|
876
|
+
agentKey: string;
|
|
877
|
+
order: number;
|
|
878
|
+
basePrice: number;
|
|
879
|
+
modelBundle: ModelBundleLine[];
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/** `outcomes.get()` — the outcome with its steps in full. */
|
|
883
|
+
export interface OutcomeWithSteps extends Outcome {
|
|
884
|
+
steps: OutcomeStep[];
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/** One step as you send it. */
|
|
888
|
+
export interface OutcomeStepInput {
|
|
889
|
+
/** An existing step's id, to keep that step (update only). A step sent
|
|
890
|
+
* without an id but with an existing step's `agentKey` is that step too. */
|
|
891
|
+
id?: string;
|
|
892
|
+
name: string;
|
|
893
|
+
agentKey: string;
|
|
894
|
+
/** Required for a new step. Leave it out on an existing step to keep its
|
|
895
|
+
* price. */
|
|
896
|
+
modelBundle?: ModelBundleLineInput[];
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/** `outcomes.create()` body. */
|
|
900
|
+
export interface CreateOutcomeInput {
|
|
901
|
+
name: string;
|
|
902
|
+
agentKey: string;
|
|
903
|
+
/** -100 or more. */
|
|
904
|
+
marginPercent: number;
|
|
905
|
+
/** 1–50 steps; names and agent keys unique. */
|
|
906
|
+
steps: OutcomeStepInput[];
|
|
907
|
+
description?: string | null;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/** `outcomes.update()` body — PARTIAL. Leave `steps` out to leave the steps
|
|
911
|
+
* alone; send it and it is the complete step list (stored steps left out are
|
|
912
|
+
* removed). */
|
|
913
|
+
export type UpdateOutcomeInput = Partial<CreateOutcomeInput>;
|
|
914
|
+
|
|
915
|
+
/** How a unit is priced. */
|
|
916
|
+
export type UnitPricingType = "FLAT" | "SLAB" | "VOLUME";
|
|
917
|
+
|
|
918
|
+
/** One price band of a SLAB / VOLUME unit. */
|
|
919
|
+
export interface UnitTier {
|
|
920
|
+
id: string;
|
|
921
|
+
/** Inclusive upper bound; `null` on the last tier ("and above"). */
|
|
922
|
+
upTo: number | null;
|
|
923
|
+
/** Per-unit price for this band. */
|
|
924
|
+
price: number;
|
|
925
|
+
order: number;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/** A unit — a fixed-price, non-LLM event (an upload, a seat, an API call). */
|
|
929
|
+
export interface Unit {
|
|
930
|
+
id: string;
|
|
931
|
+
name: string;
|
|
932
|
+
/** What a unit signal names; unique in the workspace. */
|
|
933
|
+
agentKey: string;
|
|
934
|
+
description: string | null;
|
|
935
|
+
pricingType: UnitPricingType;
|
|
936
|
+
/** FLAT only. */
|
|
937
|
+
flatPrice: number;
|
|
938
|
+
/** SLAB / VOLUME only. */
|
|
939
|
+
tiers: UnitTier[];
|
|
940
|
+
isActive: boolean;
|
|
941
|
+
createdAt: string;
|
|
942
|
+
updatedAt: string;
|
|
788
943
|
createdByName: string | null;
|
|
789
|
-
customerCount: number;
|
|
790
|
-
invoiceCount: number;
|
|
791
|
-
openInvoiceCount: number;
|
|
792
|
-
stats: { totalInvoiced: number; totalCollected: number; openBalance: number };
|
|
793
944
|
}
|
|
794
945
|
|
|
946
|
+
/** `units.create()` body. */
|
|
947
|
+
export interface CreateUnitInput {
|
|
948
|
+
name: string;
|
|
949
|
+
agentKey: string;
|
|
950
|
+
pricingType: UnitPricingType;
|
|
951
|
+
/** FLAT only. */
|
|
952
|
+
flatPrice?: number;
|
|
953
|
+
/** SLAB / VOLUME: 1–50 tiers, `upTo` rising; the last one `upTo: null`. */
|
|
954
|
+
tiers?: { upTo: number | null; price: number }[];
|
|
955
|
+
description?: string | null;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/** `units.update()` body — PARTIAL. `tiers`, when sent, is the complete list. */
|
|
959
|
+
export type UpdateUnitInput = Partial<CreateUnitInput>;
|
|
960
|
+
|
|
961
|
+
/** A catalogue item a composite wraps. */
|
|
962
|
+
export interface CompositeItem {
|
|
963
|
+
id: string;
|
|
964
|
+
name: string;
|
|
965
|
+
agentKey: string;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/** A composite — several credits / outcomes / units grouped under one tag and
|
|
969
|
+
* billed as ONE thing, per completed occurrence, once a plan sells it. */
|
|
970
|
+
export interface Composite {
|
|
971
|
+
id: string;
|
|
972
|
+
name: string;
|
|
973
|
+
/** The tag your signals send in their `composite` block. */
|
|
974
|
+
refId: string;
|
|
975
|
+
description: string | null;
|
|
976
|
+
/** USD per completed occurrence, once a plan sells it. */
|
|
977
|
+
price: number;
|
|
978
|
+
isActive: boolean;
|
|
979
|
+
createdAt: string;
|
|
980
|
+
updatedAt: string;
|
|
981
|
+
entitlements: {
|
|
982
|
+
credits: CompositeItem[];
|
|
983
|
+
outcomes: CompositeItem[];
|
|
984
|
+
units: CompositeItem[];
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/** `composites.create()` body. */
|
|
989
|
+
export interface CreateCompositeInput {
|
|
990
|
+
name: string;
|
|
991
|
+
refId: string;
|
|
992
|
+
price: number;
|
|
993
|
+
description?: string | null;
|
|
994
|
+
/** At least one id across the three lists. Every item must be active, and a
|
|
995
|
+
* unit must be FLAT-priced. */
|
|
996
|
+
entitlements: {
|
|
997
|
+
creditIds?: string[];
|
|
998
|
+
outcomeIds?: string[];
|
|
999
|
+
unitIds?: string[];
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/** `composites.update()` body — PARTIAL. `entitlements`, when sent, is the
|
|
1004
|
+
* complete new set. */
|
|
1005
|
+
export type UpdateCompositeInput = Partial<CreateCompositeInput>;
|
|
1006
|
+
|
|
795
1007
|
// ---------------------------------------------------------------------------
|
|
796
1008
|
// Purchases (subscriptions)
|
|
797
1009
|
// ---------------------------------------------------------------------------
|
|
798
1010
|
|
|
799
1011
|
export type PurchaseStatus = "SCHEDULED" | "ACTIVE" | "CANCELLED";
|
|
800
1012
|
|
|
801
|
-
export
|
|
802
|
-
customerId: string;
|
|
1013
|
+
export type CreatePurchaseInput = CustomerRef & {
|
|
803
1014
|
planId: string;
|
|
804
1015
|
/** `YYYY-MM-DD`. Defaults to today; must be a valid non-past date. */
|
|
805
1016
|
billingDate?: string;
|
|
@@ -807,7 +1018,7 @@ export interface CreatePurchaseInput {
|
|
|
807
1018
|
autoPayment?: boolean;
|
|
808
1019
|
/** Auto-void the purchase if unpaid after N minutes. */
|
|
809
1020
|
voidAfterMinutes?: number;
|
|
810
|
-
}
|
|
1021
|
+
};
|
|
811
1022
|
|
|
812
1023
|
export interface Purchase {
|
|
813
1024
|
id: string;
|
|
@@ -863,7 +1074,9 @@ export interface PurchaseDetail {
|
|
|
863
1074
|
// Invoices & Payments
|
|
864
1075
|
// ---------------------------------------------------------------------------
|
|
865
1076
|
|
|
866
|
-
|
|
1077
|
+
/** `AUTO_CLOSED` — a recurring invoice for a customer with `autoRecurring` on:
|
|
1078
|
+
* applied as if paid, but never payable. */
|
|
1079
|
+
export type InvoiceStatus = "OPEN" | "PAID" | "VOID" | "AUTO_CLOSED";
|
|
867
1080
|
|
|
868
1081
|
/** Trimmed row from `invoices.list()`. */
|
|
869
1082
|
export interface InvoiceListRow {
|
|
@@ -1048,78 +1261,84 @@ export interface UpdateMemberInput {
|
|
|
1048
1261
|
}
|
|
1049
1262
|
|
|
1050
1263
|
// ---------------------------------------------------------------------------
|
|
1051
|
-
//
|
|
1264
|
+
// Balance adjustments (customer-scoped)
|
|
1052
1265
|
// ---------------------------------------------------------------------------
|
|
1053
1266
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
*
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
export interface
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
/** What produced the entry. Null on rows older than the column. */
|
|
1071
|
-
source: WalletTransactionSource | null;
|
|
1072
|
-
amount: number;
|
|
1073
|
-
amountUsd: number;
|
|
1074
|
-
currencyCode: string;
|
|
1075
|
-
currencyRateUsd: number;
|
|
1076
|
-
notes: string | null;
|
|
1077
|
-
batchId: string | null;
|
|
1078
|
-
createdAt: string;
|
|
1079
|
-
createdByName: string | null;
|
|
1080
|
-
/** Set only on a wallet-funded metering debit: which kind of entitlement was
|
|
1081
|
-
* consumed. Null on top-ups and manual adjustments. */
|
|
1082
|
-
entitlementType: WalletEntitlementKind | null;
|
|
1083
|
-
/** Id of the credit / outcome / unit consumed. Null unless
|
|
1084
|
-
* `entitlementType` is set. */
|
|
1085
|
-
targetId: string | null;
|
|
1086
|
-
/** Its name at the time of the debit. */
|
|
1087
|
-
targetName: string | null;
|
|
1088
|
-
/** The signal this debit paid for (credit / outcome). In wallet-funded mode
|
|
1089
|
-
* no invoice exists, so this is the only trail from a charge to its cause. */
|
|
1090
|
-
usageLogId: string | null;
|
|
1091
|
-
/** The unit event this debit paid for. */
|
|
1092
|
-
unitUsageLogId: string | null;
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
export interface WalletList {
|
|
1096
|
-
balanceUsd: number;
|
|
1097
|
-
transactions: WalletTransaction[];
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
export interface WalletEntryInput {
|
|
1101
|
-
/** DEBIT spends, CREDIT tops up. */
|
|
1102
|
-
type: WalletTransactionType;
|
|
1103
|
-
/** Always positive; the sign comes from `type`. */
|
|
1104
|
-
amount: number;
|
|
1267
|
+
/**
|
|
1268
|
+
* Which of a customer's two wallet balances an entry moves: `"main"` (the
|
|
1269
|
+
* ordinary wallet) or `"reserved"` (the Reserved Wallet — an org-gated second
|
|
1270
|
+
* balance behind it; see {@link WalletAdjustInput.pool}). Lowercase only —
|
|
1271
|
+
* the API refuses `"MAIN"` / `"RESERVED"`.
|
|
1272
|
+
*/
|
|
1273
|
+
export type WalletPool = "main" | "reserved";
|
|
1274
|
+
|
|
1275
|
+
/** Top up (positive) or draw down (negative) a customer's wallet. `delta` is
|
|
1276
|
+
* a non-zero amount in USD (cents allowed); absolute value ≤ 10,000,000. No
|
|
1277
|
+
* `agentKey` — a customer has exactly one wallet. The wallet can always be
|
|
1278
|
+
* adjusted, whatever the customer's plan (even with no plan). A draw-down is
|
|
1279
|
+
* never rejected or floored for going below 0 — the wallet may read negative. */
|
|
1280
|
+
export interface WalletAdjustInput {
|
|
1281
|
+
/** Signed change in USD: positive tops up, negative draws down. */
|
|
1282
|
+
delta: number;
|
|
1105
1283
|
notes?: string;
|
|
1284
|
+
/**
|
|
1285
|
+
* Which balance to move. Default `"main"`, the ordinary wallet (leave it
|
|
1286
|
+
* out; `null` is refused).
|
|
1287
|
+
*
|
|
1288
|
+
* `"reserved"` moves the Reserved Wallet instead — a second balance behind
|
|
1289
|
+
* the wallet that a wallet-funded Arrear charge draws on once the wallet
|
|
1290
|
+
* runs out (Wallet → Reserved down to 0 → Wallet goes negative). It must be
|
|
1291
|
+
* switched on for the org (Settings → Organisation → "Enable Reserved
|
|
1292
|
+
* balance in wallet"), else this is a `PlanError`. It never goes negative:
|
|
1293
|
+
* a reduce below zero is refused (an `AllowanceError`), not capped — drawing
|
|
1294
|
+
* down to exactly 0 is fine. `remaining` is then the Reserved balance. A
|
|
1295
|
+
* `"main"` adjustment never touches it.
|
|
1296
|
+
*/
|
|
1297
|
+
pool?: WalletPool;
|
|
1298
|
+
/**
|
|
1299
|
+
* Optional idempotency key (1–255 characters) that makes this adjustment
|
|
1300
|
+
* safe to retry. The first call with a key adjusts; any repeat with the
|
|
1301
|
+
* same key and the same request adjusts nothing and comes back with
|
|
1302
|
+
* `replayed: true` (and when the original happened, `adjustedAt`). The same
|
|
1303
|
+
* key with a different request is a `ConflictError`. Keys are unique per
|
|
1304
|
+
* workspace and per adjust endpoint. **Auto-generated (UUID v4) if
|
|
1305
|
+
* omitted** and reused across every retry of this call, so a network blip
|
|
1306
|
+
* never adjusts twice — same as signals. Supply your own (e.g. your order
|
|
1307
|
+
* id) to also dedupe your OWN retries, across restarts or redelivery.
|
|
1308
|
+
*/
|
|
1309
|
+
idempotencyKey?: string;
|
|
1106
1310
|
}
|
|
1107
1311
|
|
|
1108
1312
|
/** Grant (positive) or claw back (negative) a credit balance. `delta` must be a
|
|
1109
|
-
* non-zero whole number. The credit is addressed by its stable `agentKey
|
|
1110
|
-
*
|
|
1111
|
-
*
|
|
1313
|
+
* non-zero whole number. The credit is addressed by its stable `agentKey`,
|
|
1314
|
+
* and must be a prepaid (ADVANCE) part of the customer's current plan — else
|
|
1315
|
+
* a `PlanError` ("… is not part of this customer's plan"). A reduce is never
|
|
1316
|
+
* rejected or floored for going below 0 — the resulting balance may read
|
|
1317
|
+
* negative, same as a real-usage overdraft already can. */
|
|
1112
1318
|
export interface CreditAdjustInput {
|
|
1113
1319
|
/** The credit's stable agent key (the same key used to record usage). */
|
|
1114
1320
|
agentKey: string;
|
|
1115
1321
|
delta: number;
|
|
1116
1322
|
notes?: string;
|
|
1323
|
+
/**
|
|
1324
|
+
* Optional idempotency key (1–255 characters) that makes this adjustment
|
|
1325
|
+
* safe to retry. The first call with a key adjusts; any repeat with the
|
|
1326
|
+
* same key and the same request adjusts nothing and comes back with
|
|
1327
|
+
* `replayed: true` (and when the original happened, `adjustedAt`). The same
|
|
1328
|
+
* key with a different request is a `ConflictError`. Keys are unique per
|
|
1329
|
+
* workspace and per adjust endpoint. **Auto-generated (UUID v4) if
|
|
1330
|
+
* omitted** and reused across every retry of this call, so a network blip
|
|
1331
|
+
* never adjusts twice — same as signals. Supply your own (e.g. your order
|
|
1332
|
+
* id) to also dedupe your OWN retries, across restarts or redelivery.
|
|
1333
|
+
*/
|
|
1334
|
+
idempotencyKey?: string;
|
|
1117
1335
|
}
|
|
1118
1336
|
|
|
1119
1337
|
/** Grant/claw an outcome balance. `delta` is a non-zero whole number. The
|
|
1120
1338
|
* outcome is addressed here by a STEP's `agentKey`, which resolves to its
|
|
1121
|
-
* parent outcome — NOT by the outcome's own `agentKey
|
|
1122
|
-
* which this endpoint does not accept.
|
|
1339
|
+
* parent outcome — NOT by the outcome's own `agentKey`,
|
|
1340
|
+
* which this endpoint does not accept. The outcome must be a prepaid
|
|
1341
|
+
* (ADVANCE) part of the customer's current plan — else a `PlanError`. A reduce is never rejected or floored
|
|
1123
1342
|
* for going below 0 — the resulting balance may read negative, same as a
|
|
1124
1343
|
* real-usage overdraft already can. */
|
|
1125
1344
|
export interface OutcomeAdjustInput {
|
|
@@ -1128,17 +1347,42 @@ export interface OutcomeAdjustInput {
|
|
|
1128
1347
|
agentKey: string;
|
|
1129
1348
|
delta: number;
|
|
1130
1349
|
notes?: string;
|
|
1350
|
+
/**
|
|
1351
|
+
* Optional idempotency key (1–255 characters) that makes this adjustment
|
|
1352
|
+
* safe to retry. The first call with a key adjusts; any repeat with the
|
|
1353
|
+
* same key and the same request adjusts nothing and comes back with
|
|
1354
|
+
* `replayed: true` (and when the original happened, `adjustedAt`). The same
|
|
1355
|
+
* key with a different request is a `ConflictError`. Keys are unique per
|
|
1356
|
+
* workspace and per adjust endpoint. **Auto-generated (UUID v4) if
|
|
1357
|
+
* omitted** and reused across every retry of this call, so a network blip
|
|
1358
|
+
* never adjusts twice — same as signals. Supply your own (e.g. your order
|
|
1359
|
+
* id) to also dedupe your OWN retries, across restarts or redelivery.
|
|
1360
|
+
*/
|
|
1361
|
+
idempotencyKey?: string;
|
|
1131
1362
|
}
|
|
1132
1363
|
|
|
1133
1364
|
/** Grant/claw a unit balance. `delta` is non-zero (fractional allowed). The
|
|
1134
|
-
* unit is addressed by its stable `agentKey
|
|
1135
|
-
*
|
|
1136
|
-
*
|
|
1365
|
+
* unit is addressed by its stable `agentKey`, and must be a prepaid
|
|
1366
|
+
* (ADVANCE) part of the customer's current plan — else a `PlanError`. A
|
|
1367
|
+
* reduce is never rejected or floored for going below 0 — the resulting
|
|
1368
|
+
* balance may read negative, same as a real-usage overdraft already can. */
|
|
1137
1369
|
export interface UnitAdjustInput {
|
|
1138
1370
|
/** The unit's stable agent key (the same key used to record usage). */
|
|
1139
1371
|
agentKey: string;
|
|
1140
1372
|
delta: number;
|
|
1141
1373
|
notes?: string;
|
|
1374
|
+
/**
|
|
1375
|
+
* Optional idempotency key (1–255 characters) that makes this adjustment
|
|
1376
|
+
* safe to retry. The first call with a key adjusts; any repeat with the
|
|
1377
|
+
* same key and the same request adjusts nothing and comes back with
|
|
1378
|
+
* `replayed: true` (and when the original happened, `adjustedAt`). The same
|
|
1379
|
+
* key with a different request is a `ConflictError`. Keys are unique per
|
|
1380
|
+
* workspace and per adjust endpoint. **Auto-generated (UUID v4) if
|
|
1381
|
+
* omitted** and reused across every retry of this call, so a network blip
|
|
1382
|
+
* never adjusts twice — same as signals. Supply your own (e.g. your order
|
|
1383
|
+
* id) to also dedupe your OWN retries, across restarts or redelivery.
|
|
1384
|
+
*/
|
|
1385
|
+
idempotencyKey?: string;
|
|
1142
1386
|
}
|
|
1143
1387
|
|
|
1144
1388
|
/**
|
|
@@ -1151,7 +1395,7 @@ export interface UnitAdjustInput {
|
|
|
1151
1395
|
*/
|
|
1152
1396
|
export interface CompositeAdjustInput {
|
|
1153
1397
|
/**
|
|
1154
|
-
* The composite's stable identifier — its `refId
|
|
1398
|
+
* The composite's stable identifier — its `refId`,
|
|
1155
1399
|
* the same value signals tag it with, NOT `agentKey` (a composite has no
|
|
1156
1400
|
* `agentKey` column of its own). Named `agentKey` on the wire only so the
|
|
1157
1401
|
* four adjust endpoints share one request shape.
|
|
@@ -1159,266 +1403,64 @@ export interface CompositeAdjustInput {
|
|
|
1159
1403
|
agentKey: string;
|
|
1160
1404
|
delta: number;
|
|
1161
1405
|
notes?: string;
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
// ---------------------------------------------------------------------------
|
|
1165
|
-
// Entitlement catalogs: Credits, Outcomes, Units
|
|
1166
|
-
// ---------------------------------------------------------------------------
|
|
1167
|
-
|
|
1168
|
-
/** A per-model token bundle attached to a credit or outcome step. */
|
|
1169
|
-
export interface ModelBundleEntry {
|
|
1170
|
-
orgModelId: string;
|
|
1171
|
-
/** Display label; the server defaults it from the model when omitted. */
|
|
1172
|
-
modelName?: string;
|
|
1173
|
-
tokens: number;
|
|
1174
|
-
input: number;
|
|
1175
|
-
output: number;
|
|
1176
|
-
cache: number;
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
/** One point on a cost-over-time analytics series. */
|
|
1180
|
-
export interface CostPoint {
|
|
1181
|
-
/** UTC day, `YYYY-MM-DD`. */
|
|
1182
|
-
dateIso: string;
|
|
1183
|
-
/** Short display label, e.g. "Jun 24". */
|
|
1184
|
-
label: string;
|
|
1185
|
-
/** Average cost that day, or `null` on days with no usage. */
|
|
1186
|
-
cost: number | null;
|
|
1187
|
-
reqs: number;
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
/** Summary stats across a cost-over-time series. */
|
|
1191
|
-
export interface CostStats {
|
|
1192
|
-
activeDays: number;
|
|
1193
|
-
avgCost: number | null;
|
|
1194
|
-
peakCost: number | null;
|
|
1195
|
-
troughCost: number | null;
|
|
1196
|
-
deviationPct: number | null;
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
/** Cost-over-time analytics for a credit (`credits.get().analytics`). */
|
|
1200
|
-
export interface CreditAnalytics {
|
|
1201
|
-
basePrice: number;
|
|
1202
|
-
pricePerCredit: number;
|
|
1203
|
-
marginPercent: number;
|
|
1204
|
-
points: CostPoint[];
|
|
1205
|
-
stats: CostStats;
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
/** Cost-over-time analytics for an outcome (`outcomes.get().analytics`).
|
|
1209
|
-
* Each point adds `completions` (workflows finished that day). */
|
|
1210
|
-
export interface OutcomeAnalytics {
|
|
1211
|
-
basePrice: number;
|
|
1212
|
-
pricePerOutcome: number;
|
|
1213
|
-
marginPercent: number;
|
|
1214
|
-
points: (CostPoint & { completions: number })[];
|
|
1215
|
-
stats: CostStats;
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
export interface Credit {
|
|
1219
|
-
id: string;
|
|
1220
|
-
name: string;
|
|
1221
|
-
agentKey: string;
|
|
1222
|
-
description: string | null;
|
|
1223
|
-
tokensPerCredit: number;
|
|
1224
|
-
basePrice: number;
|
|
1225
|
-
marginPercent: number;
|
|
1226
|
-
pricePerCredit: number;
|
|
1227
|
-
isActive: boolean;
|
|
1228
|
-
createdAt: string;
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
/** `credits.get()` — adds the model bundle plus usage stats/analytics. */
|
|
1232
|
-
export interface CreditDetail extends Credit {
|
|
1233
|
-
modelBundle: ModelBundleEntry[];
|
|
1234
|
-
createdByName: string;
|
|
1235
|
-
stats: {
|
|
1236
|
-
customerCount: number;
|
|
1237
|
-
planCount: number;
|
|
1238
|
-
totalGranted: number;
|
|
1239
|
-
totalUsed: number;
|
|
1240
|
-
revenue: number;
|
|
1241
|
-
usageLogCount: number;
|
|
1242
|
-
};
|
|
1243
|
-
analytics: CreditAnalytics;
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
export interface CreateCreditInput {
|
|
1247
|
-
name: string;
|
|
1248
|
-
/** Lowercased stable key used by `signals.credit({ agentKey })`. */
|
|
1249
|
-
agentKey: string;
|
|
1250
|
-
basePrice: number;
|
|
1251
|
-
marginPercent: number;
|
|
1252
|
-
pricePerCredit: number;
|
|
1253
|
-
description?: string;
|
|
1254
|
-
tokensPerCredit?: number;
|
|
1255
|
-
modelBundle?: ModelBundleEntry[];
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
export type UpdateCreditInput = CreateCreditInput;
|
|
1259
|
-
|
|
1260
|
-
export interface OutcomeStepInput {
|
|
1261
|
-
id?: string;
|
|
1262
|
-
name: string;
|
|
1263
|
-
/** Lowercased stable key used by `signals.outcome({ agentKey })`. */
|
|
1264
|
-
agentKey: string;
|
|
1265
|
-
basePrice: number;
|
|
1266
|
-
modelBundle?: ModelBundleEntry[];
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
export interface Outcome {
|
|
1270
|
-
id: string;
|
|
1271
|
-
name: string;
|
|
1272
|
-
/**
|
|
1273
|
-
* The OUTCOME's own stable agent key — its durable identity, mirroring
|
|
1274
|
-
* {@link Credit.agentKey}. Lowercased `[a-z0-9._-]`, max 80 chars, unique per
|
|
1275
|
-
* organisation. A rename never changes it.
|
|
1276
|
-
*
|
|
1277
|
-
* Distinct from each step's `agentKey` in `steps`, and in a SEPARATE
|
|
1278
|
-
* namespace: usage is always reported against a STEP's key
|
|
1279
|
-
* (`signals.outcome({ agentKey })`), never this one. This key identifies the
|
|
1280
|
-
* outcome itself when creating or updating it.
|
|
1281
|
-
*/
|
|
1282
|
-
agentKey: string;
|
|
1283
|
-
description: string | null;
|
|
1284
|
-
isActive: boolean;
|
|
1285
|
-
marginPercent: number;
|
|
1286
|
-
pricePerOutcome: number;
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
/** `outcomes.get()` — adds steps plus in-flight/completed stats. */
|
|
1290
|
-
export interface OutcomeDetail extends Outcome {
|
|
1291
|
-
/** Only the DETAIL row carries these — `outcomes.list()` returns neither.
|
|
1292
|
-
* They were previously declared on {@link Outcome} itself, where
|
|
1293
|
-
* `createdAt` was typed as a required `string` that is always `undefined`
|
|
1294
|
-
* in practice. */
|
|
1295
|
-
createdAt: string;
|
|
1296
|
-
createdByName: string | null;
|
|
1297
|
-
steps: { name: string; agentKey: string }[];
|
|
1298
|
-
stats: {
|
|
1299
|
-
stepCount: number;
|
|
1300
|
-
customerCount: number;
|
|
1301
|
-
inFlight: number;
|
|
1302
|
-
completed: number;
|
|
1303
|
-
totalRemaining: number;
|
|
1304
|
-
};
|
|
1305
|
-
analytics: OutcomeAnalytics;
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
export interface CreateOutcomeInput {
|
|
1309
|
-
name: string;
|
|
1310
1406
|
/**
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
* key
|
|
1316
|
-
*
|
|
1407
|
+
* Optional idempotency key (1–255 characters) that makes this adjustment
|
|
1408
|
+
* safe to retry. The first call with a key adjusts; any repeat with the
|
|
1409
|
+
* same key and the same request adjusts nothing and comes back with
|
|
1410
|
+
* `replayed: true` (and when the original happened, `adjustedAt`). The same
|
|
1411
|
+
* key with a different request is a `ConflictError`. Keys are unique per
|
|
1412
|
+
* workspace and per adjust endpoint. **Auto-generated (UUID v4) if
|
|
1413
|
+
* omitted** and reused across every retry of this call, so a network blip
|
|
1414
|
+
* never adjusts twice — same as signals. Supply your own (e.g. your order
|
|
1415
|
+
* id) to also dedupe your OWN retries, across restarts or redelivery.
|
|
1317
1416
|
*/
|
|
1318
|
-
|
|
1319
|
-
basePrice: number;
|
|
1320
|
-
marginPercent: number;
|
|
1321
|
-
pricePerOutcome: number;
|
|
1322
|
-
description?: string | null;
|
|
1323
|
-
isActive?: boolean;
|
|
1324
|
-
/** 1–50 steps; step names and agent keys must be unique. */
|
|
1325
|
-
steps: OutcomeStepInput[];
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
export type UpdateOutcomeInput = CreateOutcomeInput;
|
|
1329
|
-
|
|
1330
|
-
export type UnitPricingType = "FLAT" | "SLAB" | "VOLUME";
|
|
1331
|
-
|
|
1332
|
-
/** A tier for SLAB/VOLUME pricing; only the last tier may have `upTo: null`. */
|
|
1333
|
-
export interface UnitTierInput {
|
|
1334
|
-
id?: string;
|
|
1335
|
-
upTo: number | null;
|
|
1336
|
-
price: number;
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
export interface UnitTier {
|
|
1340
|
-
id: string;
|
|
1341
|
-
upTo: number | null;
|
|
1342
|
-
price: number;
|
|
1343
|
-
order: number;
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
export interface Unit {
|
|
1347
|
-
id: string;
|
|
1348
|
-
/** Stable per-org report key — what `signals.unit({ agentKey })` sends.
|
|
1349
|
-
* The ONLY identifier accepted when reporting unit consumption. */
|
|
1350
|
-
agentKey: string;
|
|
1351
|
-
name: string;
|
|
1352
|
-
description: string | null;
|
|
1353
|
-
pricingType: UnitPricingType;
|
|
1354
|
-
flatPrice: number;
|
|
1355
|
-
tiers: UnitTier[];
|
|
1356
|
-
isActive: boolean;
|
|
1357
|
-
createdAt: string;
|
|
1358
|
-
createdByName: string | null;
|
|
1417
|
+
idempotencyKey?: string;
|
|
1359
1418
|
}
|
|
1360
1419
|
|
|
1361
|
-
/**
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1420
|
+
/**
|
|
1421
|
+
* What every adjust call returns.
|
|
1422
|
+
*
|
|
1423
|
+
* `replayed: true` means this call adjusted NOTHING: an earlier call with the
|
|
1424
|
+
* same `idempotencyKey` already did, at `adjustedAt`. `remaining` is always
|
|
1425
|
+
* the balance as it is now. `customerArchived` is true when the customer is
|
|
1426
|
+
* archived — archived customers follow the same rules (archiving cancels
|
|
1427
|
+
* their plan, so usually only the wallet can still move).
|
|
1428
|
+
*/
|
|
1429
|
+
export interface AdjustResult {
|
|
1370
1430
|
remaining: number;
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
* `createdByName` is inherited from `Unit`. */
|
|
1376
|
-
export interface UnitDetail extends Unit {
|
|
1377
|
-
stats: {
|
|
1378
|
-
planCount: number;
|
|
1379
|
-
customerCount: number;
|
|
1380
|
-
totalRemaining: number;
|
|
1381
|
-
totalUsed: number;
|
|
1382
|
-
};
|
|
1383
|
-
/** First page (≤10) of customers currently metered on this unit. */
|
|
1384
|
-
customers: UnitCustomerRow[];
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
/** Flat per-event pricing — a single `flatPrice` (defaults to 0), no tiers. */
|
|
1388
|
-
export interface FlatUnitInput {
|
|
1389
|
-
name: string;
|
|
1390
|
-
/** Stable per-org report key (`signals.unit({ agentKey })`); `[a-z0-9._-]`. */
|
|
1391
|
-
agentKey: string;
|
|
1392
|
-
pricingType: "FLAT";
|
|
1393
|
-
/** Price per event; defaults to 0. */
|
|
1394
|
-
flatPrice?: number;
|
|
1395
|
-
description?: string | null;
|
|
1396
|
-
isActive?: boolean;
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
/** Tiered pricing (SLAB or VOLUME) — at least one tier is required. */
|
|
1400
|
-
export interface TieredUnitInput {
|
|
1401
|
-
name: string;
|
|
1402
|
-
/** Stable per-org report key (`signals.unit({ agentKey })`); `[a-z0-9._-]`. */
|
|
1403
|
-
agentKey: string;
|
|
1404
|
-
pricingType: "SLAB" | "VOLUME";
|
|
1405
|
-
/** At least one tier (≤50). Only the last tier may have `upTo: null`. */
|
|
1406
|
-
tiers: UnitTierInput[];
|
|
1407
|
-
description?: string | null;
|
|
1408
|
-
isActive?: boolean;
|
|
1431
|
+
replayed: boolean;
|
|
1432
|
+
/** Set only on a replay: when the original adjustment happened (ISO 8601). */
|
|
1433
|
+
adjustedAt?: string;
|
|
1434
|
+
customerArchived: boolean;
|
|
1409
1435
|
}
|
|
1410
1436
|
|
|
1411
1437
|
/**
|
|
1412
|
-
*
|
|
1413
|
-
*
|
|
1414
|
-
*
|
|
1438
|
+
* Change how much a customer is granted every billing cycle. The difference is
|
|
1439
|
+
* applied to the current balance immediately (a shrink is never floored — the
|
|
1440
|
+
* balance may read negative). `quantity` is USD for the wallet and a whole
|
|
1441
|
+
* number for everything else. `agentKey` resolves the same way as the adjust
|
|
1442
|
+
* endpoints: a credit's or unit's `agentKey`, an outcome STEP's `agentKey`, or
|
|
1443
|
+
* a composite's `refId`. The wallet needs none — a customer has at most one.
|
|
1415
1444
|
*/
|
|
1416
|
-
export type
|
|
1445
|
+
export type RecurringGrantInput =
|
|
1446
|
+
| { kind: "wallet"; quantity: number }
|
|
1447
|
+
| {
|
|
1448
|
+
kind: "credit" | "outcome" | "unit" | "composite";
|
|
1449
|
+
agentKey: string;
|
|
1450
|
+
quantity: number;
|
|
1451
|
+
};
|
|
1417
1452
|
|
|
1418
|
-
|
|
1453
|
+
/** Result of `customers.updateRecurringGrant()`. */
|
|
1454
|
+
export interface RecurringGrantResult {
|
|
1455
|
+
kind: RecurringGrantInput["kind"];
|
|
1456
|
+
/** The new per-cycle amount. */
|
|
1457
|
+
quantity: number;
|
|
1458
|
+
/** The wallet balance after the change — only present for `kind: "wallet"`. */
|
|
1459
|
+
balanceUsd?: number;
|
|
1460
|
+
}
|
|
1419
1461
|
|
|
1420
1462
|
// ---------------------------------------------------------------------------
|
|
1421
|
-
// Unit consumption (recorded via signals
|
|
1463
|
+
// Unit consumption (recorded via signals)
|
|
1422
1464
|
// ---------------------------------------------------------------------------
|
|
1423
1465
|
|
|
1424
1466
|
/**
|
|
@@ -1427,8 +1469,7 @@ export type UpdateUnitInput = CreateUnitInput;
|
|
|
1427
1469
|
* the display name is deliberately not accepted, so a rename can never redirect
|
|
1428
1470
|
* a live integration. Keys are matched exactly (they are stored lowercased).
|
|
1429
1471
|
*/
|
|
1430
|
-
export
|
|
1431
|
-
customerId: string;
|
|
1472
|
+
export type UnitInput = CustomerRef & {
|
|
1432
1473
|
agentKey: string;
|
|
1433
1474
|
member?: string;
|
|
1434
1475
|
/**
|
|
@@ -1459,7 +1500,7 @@ export interface UnitInput {
|
|
|
1459
1500
|
* auto key cannot survive.
|
|
1460
1501
|
*/
|
|
1461
1502
|
idempotencyKey?: string;
|
|
1462
|
-
}
|
|
1503
|
+
};
|
|
1463
1504
|
|
|
1464
1505
|
/**
|
|
1465
1506
|
* The result of `signals.unit()`.
|
|
@@ -1489,8 +1530,7 @@ export interface UnitTrackResult {
|
|
|
1489
1530
|
* Input for `signals.completeComposite()` — closes ONE occurrence of a
|
|
1490
1531
|
* composite, which is the moment it is billed.
|
|
1491
1532
|
*/
|
|
1492
|
-
export
|
|
1493
|
-
customerId: string;
|
|
1533
|
+
export type CompositeCompletionInput = CustomerRef & {
|
|
1494
1534
|
/** Which occurrence to close: the composite's `refId` and the correlation
|
|
1495
1535
|
* value the signals were tagged with. */
|
|
1496
1536
|
composite: CompositeTag;
|
|
@@ -1498,79 +1538,12 @@ export interface CompositeCompletionInput {
|
|
|
1498
1538
|
* safe no-op, so this only collapses retries into one recorded attempt
|
|
1499
1539
|
* rather than protecting against a double charge. */
|
|
1500
1540
|
idempotencyKey?: string;
|
|
1501
|
-
}
|
|
1541
|
+
};
|
|
1502
1542
|
|
|
1503
1543
|
// ---------------------------------------------------------------------------
|
|
1504
|
-
//
|
|
1544
|
+
// Composite completion
|
|
1505
1545
|
// ---------------------------------------------------------------------------
|
|
1506
1546
|
|
|
1507
|
-
/** One catalogue item a composite is restricted to. `agentKey` is what a
|
|
1508
|
-
* signal names, so it is the field you actually integrate against. */
|
|
1509
|
-
export interface CompositeCatalogueRef {
|
|
1510
|
-
id: string;
|
|
1511
|
-
name: string;
|
|
1512
|
-
agentKey: string;
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
/** One composite in the org's catalogue — `cnk.composites.list()`. */
|
|
1516
|
-
export interface Composite {
|
|
1517
|
-
id: string;
|
|
1518
|
-
name: string;
|
|
1519
|
-
/** The stable identifier you put in a signal's `composite` block as `ref`. */
|
|
1520
|
-
refId: string;
|
|
1521
|
-
description: string | null;
|
|
1522
|
-
/** USD charged per occurrence WHEN A PLAN SELLS THIS as a composite
|
|
1523
|
-
* component (`quantity × price`, frozen into the purchase at buy time). The
|
|
1524
|
-
* catalogue row alone bills nothing. */
|
|
1525
|
-
price: number;
|
|
1526
|
-
/** False once archived. An archived composite stops NEW signals resolving to
|
|
1527
|
-
* it but keeps every row it already owns. */
|
|
1528
|
-
isActive: boolean;
|
|
1529
|
-
createdAt: string;
|
|
1530
|
-
/**
|
|
1531
|
-
* The credits / outcomes / units this composite is restricted to — only
|
|
1532
|
-
* signals naming one of these may carry its tag.
|
|
1533
|
-
*
|
|
1534
|
-
* All three lists empty means UNRESTRICTED (it accepts any of the org's
|
|
1535
|
-
* traffic under this tag). Nothing created through the API can be
|
|
1536
|
-
* unrestricted, but rows predating that rule exist — so don't assume
|
|
1537
|
-
* non-empty.
|
|
1538
|
-
*/
|
|
1539
|
-
entitlements: {
|
|
1540
|
-
credits: CompositeCatalogueRef[];
|
|
1541
|
-
outcomes: CompositeCatalogueRef[];
|
|
1542
|
-
units: CompositeCatalogueRef[];
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
/** Input for `cnk.composites.create()`. */
|
|
1547
|
-
export interface CreateCompositeInput {
|
|
1548
|
-
name: string;
|
|
1549
|
-
/**
|
|
1550
|
-
* The tag identifier. Lowercased, and restricted to the same characters as
|
|
1551
|
-
* an `agentKey` — but validated harder than one, because it may not collide
|
|
1552
|
-
* with a field the ingest schemas already own (`customerId`, `usage`,
|
|
1553
|
-
* `agentKey`, `runId`, `member`, `custom`, `composite`, …). A colliding
|
|
1554
|
-
* `refId` is refused at create time rather than silently ignored at ingest.
|
|
1555
|
-
*/
|
|
1556
|
-
refId: string;
|
|
1557
|
-
/** USD per occurrence once a plan sells it. Required — an unpriced composite
|
|
1558
|
-
* put on a plan would bill 0, which is a money bug that is hard to see. */
|
|
1559
|
-
price: number;
|
|
1560
|
-
description?: string | null;
|
|
1561
|
-
/**
|
|
1562
|
-
* What the composite wraps. At least one id across the three lists is
|
|
1563
|
-
* REQUIRED: a composite restricted to nothing would accept every signal in
|
|
1564
|
-
* the org. Get the ids from `credits.list()`, `outcomes.list()` and
|
|
1565
|
-
* `units.list()`.
|
|
1566
|
-
*/
|
|
1567
|
-
entitlements: {
|
|
1568
|
-
creditIds?: string[];
|
|
1569
|
-
outcomeIds?: string[];
|
|
1570
|
-
unitIds?: string[];
|
|
1571
|
-
};
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
1547
|
/**
|
|
1575
1548
|
* The result of `signals.completeComposite()`.
|
|
1576
1549
|
*
|
|
@@ -1603,8 +1576,7 @@ export interface CompositeCompletionResult {
|
|
|
1603
1576
|
rawId?: string;
|
|
1604
1577
|
}
|
|
1605
1578
|
|
|
1606
|
-
/** One serialized unit-consumption event — the result of `signals.unit()
|
|
1607
|
-
* each element of `UnitUsageList.events`. */
|
|
1579
|
+
/** One serialized unit-consumption event — the result of `signals.unit()`. */
|
|
1608
1580
|
export interface SerializedUnitUsage {
|
|
1609
1581
|
id: string;
|
|
1610
1582
|
customerId: string;
|
|
@@ -1620,48 +1592,6 @@ export interface SerializedUnitUsage {
|
|
|
1620
1592
|
createdAt: string;
|
|
1621
1593
|
}
|
|
1622
1594
|
|
|
1623
|
-
export interface UnitUsageRow {
|
|
1624
|
-
unit: string;
|
|
1625
|
-
/** The unit's stable agent key — what to send to report against it. */
|
|
1626
|
-
agentKey: string | null;
|
|
1627
|
-
billingMode: BillingMode;
|
|
1628
|
-
granted?: number;
|
|
1629
|
-
used: number;
|
|
1630
|
-
remaining?: number;
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
export interface UnitUsageList {
|
|
1634
|
-
customer: { id: string; name: string };
|
|
1635
|
-
units: UnitUsageRow[];
|
|
1636
|
-
events: SerializedUnitUsage[];
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
// ---------------------------------------------------------------------------
|
|
1640
|
-
// Webhooks (threshold alerts)
|
|
1641
|
-
// ---------------------------------------------------------------------------
|
|
1642
|
-
|
|
1643
|
-
export type ThresholdKind = "CREDIT" | "OUTCOME" | "WALLET";
|
|
1644
|
-
|
|
1645
|
-
export interface Webhook {
|
|
1646
|
-
id: string;
|
|
1647
|
-
kind: ThresholdKind;
|
|
1648
|
-
threshold: number;
|
|
1649
|
-
url: string;
|
|
1650
|
-
isActive: boolean;
|
|
1651
|
-
createdAt: string;
|
|
1652
|
-
updatedAt: string;
|
|
1653
|
-
createdByName: string | null;
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
export interface UpsertWebhookInput {
|
|
1657
|
-
kind: ThresholdKind;
|
|
1658
|
-
/** Fire when the balance crosses this value. */
|
|
1659
|
-
threshold: number;
|
|
1660
|
-
/** http(s) URL to POST the alert to. */
|
|
1661
|
-
url: string;
|
|
1662
|
-
isActive?: boolean;
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
1595
|
// ---------------------------------------------------------------------------
|
|
1666
1596
|
// Config & hooks
|
|
1667
1597
|
// ---------------------------------------------------------------------------
|