@clocknext/sdk 0.8.0 → 0.10.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 +77 -15
- package/dist/index.cjs +166 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +387 -61
- package/dist/index.d.ts +387 -61
- package/dist/index.js +166 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Public types for the ClockNext SDK.
|
|
3
3
|
*
|
|
4
|
-
* The signal types mirror the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The signal types mirror the bodies of the `/api/v1/signal/*` routes as a
|
|
5
|
+
* discriminated union, so the per-kind required fields the server enforces with
|
|
6
|
+
* Zod are enforced here at compile time instead of surfacing as runtime 400s.
|
|
7
|
+
*
|
|
8
|
+
* The server now has one schema per route rather than one schema with a `type`
|
|
9
|
+
* discriminator, which is why `type` no longer appears on the wire — it selects
|
|
10
|
+
* the route instead. It stays on these types because it is still the
|
|
11
|
+
* discriminator callers write and TypeScript narrows on.
|
|
8
12
|
*/
|
|
9
13
|
type SignalType = "wallet" | "credit" | "outcome";
|
|
10
14
|
type SignalStatus = "SUCCESS" | "FAILURE" | "PENDING";
|
|
@@ -19,18 +23,37 @@ interface Tokens {
|
|
|
19
23
|
cache?: number;
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* Groups a signal into one occurrence of a **composite** — a bundle of credits
|
|
27
|
+
* / outcomes / units that is priced and billed as a single thing.
|
|
28
|
+
*
|
|
29
|
+
* `ref` is the composite's `refId` (defined in the dashboard) and `value` is
|
|
30
|
+
* your own correlation id for one occurrence: a session, a call, a job. Every
|
|
31
|
+
* signal sharing a value belongs to the same occurrence.
|
|
32
|
+
*
|
|
33
|
+
* This is NOT reporting-only (earlier versions of this SDK called it a
|
|
34
|
+
* "pricing metric" and said so — that was wrong). Where the customer's plan
|
|
35
|
+
* sells the composite, the occurrence IS the billable unit: it opens on the
|
|
36
|
+
* first tagged signal costing nothing, and is charged once when you close it
|
|
37
|
+
* with `signals.completeComposite()` — claiming a prepaid slot on an ADVANCE
|
|
38
|
+
* component, or becoming countable on an ARREAR one.
|
|
39
|
+
*
|
|
40
|
+
* What stays true is that a bad tag never fails the signal: a `ref` naming no
|
|
41
|
+
* live composite is ignored rather than rejected, because the signal carries
|
|
42
|
+
* money and the tag only decides what it is grouped under. Applies to credit,
|
|
43
|
+
* outcome and unit signals; a tag on a wallet signal is accepted and ignored,
|
|
44
|
+
* since raw wallet spend is not entitlement traffic.
|
|
45
|
+
*
|
|
46
|
+
* Only ONE composite per signal is expressible here. The wire format accepts
|
|
47
|
+
* several (`composite` is an object of ref → value), so if you need a signal
|
|
48
|
+
* in two composites at once, that is the limit to lift.
|
|
28
49
|
*/
|
|
29
|
-
interface
|
|
30
|
-
/** The
|
|
31
|
-
*
|
|
50
|
+
interface CompositeTag {
|
|
51
|
+
/** The composite's `refId`. Case-insensitive. Unlike earlier versions this
|
|
52
|
+
* no longer shares a namespace with the ingest fields — the tag is nested
|
|
53
|
+
* under `composite` on the wire — so a composite may safely be called
|
|
54
|
+
* `model`, `status`, or anything else. */
|
|
32
55
|
ref: string;
|
|
33
|
-
/** Your correlation value for this
|
|
56
|
+
/** Your correlation value for this occurrence, stored verbatim. */
|
|
34
57
|
value: string | number;
|
|
35
58
|
}
|
|
36
59
|
/** The organisation + key behind a request — `cnk.workspace.me()`. */
|
|
@@ -90,8 +113,8 @@ interface CreditSignal extends SignalBase {
|
|
|
90
113
|
type: "credit";
|
|
91
114
|
/** The Credit's stable agent key (assigned when the credit was created). */
|
|
92
115
|
agentKey: string;
|
|
93
|
-
/** Optional
|
|
94
|
-
|
|
116
|
+
/** Optional composite this signal belongs to. See {@link CompositeTag}. */
|
|
117
|
+
composite?: CompositeTag;
|
|
95
118
|
}
|
|
96
119
|
/** Debits the customer's wallet in USD at the model's cost. */
|
|
97
120
|
interface WalletSignal extends SignalBase {
|
|
@@ -118,8 +141,8 @@ interface OutcomeSignal extends SignalBase {
|
|
|
118
141
|
* can't bill again.
|
|
119
142
|
*/
|
|
120
143
|
complete?: boolean;
|
|
121
|
-
/** Optional
|
|
122
|
-
|
|
144
|
+
/** Optional composite this signal belongs to. See {@link CompositeTag}. */
|
|
145
|
+
composite?: CompositeTag;
|
|
123
146
|
}
|
|
124
147
|
type Signal = CreditSignal | WalletSignal | OutcomeSignal;
|
|
125
148
|
/** Helper input shapes for the per-type convenience methods. */
|
|
@@ -217,6 +240,18 @@ interface TrackResult {
|
|
|
217
240
|
* (server-side queueing). Absent for client-side buffering and for inline
|
|
218
241
|
* pricing. */
|
|
219
242
|
messageId?: string;
|
|
243
|
+
/**
|
|
244
|
+
* The signal's durable inbox id, returned by every `/api/v1/signal/*`
|
|
245
|
+
* response — the `202` hand-off AND inline pricing. Present whenever the
|
|
246
|
+
* server has written the request down, which it now does BEFORE validating
|
|
247
|
+
* or pricing it, so a `rawId` means "this signal cannot be lost" even when
|
|
248
|
+
* `usageLog` is null. Quote it when asking why a signal has not been billed;
|
|
249
|
+
* it is the row the dashboard shows as Processing / Pending / Processed.
|
|
250
|
+
*
|
|
251
|
+
* Absent while the signal sits in the client-side buffer (nothing has been
|
|
252
|
+
* sent yet, so the server has no id for it).
|
|
253
|
+
*/
|
|
254
|
+
rawId?: string;
|
|
220
255
|
}
|
|
221
256
|
interface UsageList {
|
|
222
257
|
customer: {
|
|
@@ -243,14 +278,11 @@ interface ApiCustomer {
|
|
|
243
278
|
phone: string | null;
|
|
244
279
|
legalName: string | null;
|
|
245
280
|
addressLine1: string | null;
|
|
246
|
-
addressLine2: string | null;
|
|
247
281
|
city: string | null;
|
|
248
282
|
state: string | null;
|
|
249
283
|
country: string | null;
|
|
250
284
|
pincode: string | null;
|
|
251
285
|
taxId: string | null;
|
|
252
|
-
notes: string | null;
|
|
253
|
-
logoUrl: string | null;
|
|
254
286
|
currencyCode: string;
|
|
255
287
|
creditAllowance: number;
|
|
256
288
|
createdAt: string;
|
|
@@ -265,14 +297,11 @@ interface CustomerProfileInput {
|
|
|
265
297
|
phone?: string | null;
|
|
266
298
|
legalName?: string | null;
|
|
267
299
|
addressLine1?: string | null;
|
|
268
|
-
addressLine2?: string | null;
|
|
269
300
|
city?: string | null;
|
|
270
301
|
state?: string | null;
|
|
271
302
|
country?: string | null;
|
|
272
303
|
pincode?: string | null;
|
|
273
304
|
taxId?: string | null;
|
|
274
|
-
notes?: string | null;
|
|
275
|
-
logoUrl?: string | null;
|
|
276
305
|
/** ISO 4217 (3 letters); must be enabled for the org. */
|
|
277
306
|
currencyCode?: string;
|
|
278
307
|
}
|
|
@@ -443,15 +472,49 @@ type UnitComponentInput = {
|
|
|
443
472
|
unitId: string;
|
|
444
473
|
quantity?: number | null;
|
|
445
474
|
};
|
|
475
|
+
/**
|
|
476
|
+
* A COMPOSITE sold on the plan, referenced by `pricingMetricId` (the id from
|
|
477
|
+
* `composites.list()`). This is the line that makes a composite bill: the
|
|
478
|
+
* catalogue entry on its own charges nobody, and this component is what turns
|
|
479
|
+
* it into money — `quantity × the composite's price`, frozen into the purchase
|
|
480
|
+
* snapshot at buy time.
|
|
481
|
+
*
|
|
482
|
+
* The two billing modes differ in what `quantity` means:
|
|
483
|
+
* - **ADVANCE** — a PREPAID POOL of `quantity` flat-rate slots, shared
|
|
484
|
+
* across whichever credits / outcomes / units the composite wraps. Each
|
|
485
|
+
* distinct tag value claims one slot on completion; repeat signals under a
|
|
486
|
+
* value reuse the slot they already claimed, at no extra cost. Once every
|
|
487
|
+
* slot is claimed, further occurrences are refused rather than billed.
|
|
488
|
+
* - **ARREAR** — nothing prepaid; completed occurrences are counted on the
|
|
489
|
+
* cycle-end line.
|
|
490
|
+
*
|
|
491
|
+
* `type` is the wire value `"PRICING_METRIC"`, not `"COMPOSITE"`: the product
|
|
492
|
+
* word changed but the stored enum did not, and the API still speaks the old
|
|
493
|
+
* one. That mismatch is the server's, and it is surfaced rather than hidden so
|
|
494
|
+
* a response and a request read the same.
|
|
495
|
+
*/
|
|
496
|
+
type CompositeComponentInput = {
|
|
497
|
+
type: "PRICING_METRIC";
|
|
498
|
+
billingMode: "ADVANCE";
|
|
499
|
+
pricingMetricId: string;
|
|
500
|
+
quantity: number;
|
|
501
|
+
} | {
|
|
502
|
+
type: "PRICING_METRIC";
|
|
503
|
+
billingMode: "ARREAR";
|
|
504
|
+
pricingMetricId: string;
|
|
505
|
+
quantity?: number | null;
|
|
506
|
+
};
|
|
446
507
|
/**
|
|
447
508
|
* One entitlement line in a plan — a discriminated union on `type` (and, where
|
|
448
509
|
* it matters, `billingMode`) so the per-type fields the server requires are
|
|
449
510
|
* enforced at compile time instead of surfacing as runtime 422s:
|
|
450
511
|
* - CREDIT / OUTCOME / UNIT require their matching id;
|
|
451
|
-
* -
|
|
512
|
+
* - PRICING_METRIC (a composite) requires `pricingMetricId`;
|
|
513
|
+
* - CREDIT / OUTCOME / UNIT / PRICING_METRIC require `quantity` when billed
|
|
514
|
+
* ADVANCE;
|
|
452
515
|
* - WALLET / FLAT require `amount`.
|
|
453
516
|
*/
|
|
454
|
-
type PlanComponentInput = WalletComponentInput | FlatComponentInput | CreditComponentInput | OutcomeComponentInput | UnitComponentInput;
|
|
517
|
+
type PlanComponentInput = WalletComponentInput | FlatComponentInput | CreditComponentInput | OutcomeComponentInput | UnitComponentInput | CompositeComponentInput;
|
|
455
518
|
interface CreatePlanInput {
|
|
456
519
|
name: string;
|
|
457
520
|
description?: string | null;
|
|
@@ -703,31 +766,36 @@ interface PaymentDetail {
|
|
|
703
766
|
payment: Invoice;
|
|
704
767
|
plan: PlanRef | null;
|
|
705
768
|
}
|
|
706
|
-
|
|
769
|
+
/** A customer member as returned by `listMembers` (`GET .../members`). */
|
|
707
770
|
interface Member {
|
|
708
771
|
id: string;
|
|
709
|
-
role: MemberRole;
|
|
710
772
|
name: string;
|
|
711
773
|
email: string | null;
|
|
712
|
-
employeeId: string | null;
|
|
713
|
-
phone: string | null;
|
|
714
774
|
/** True once the member has linked a login. */
|
|
715
775
|
isLinked: boolean;
|
|
716
776
|
joinedAt: string;
|
|
717
777
|
}
|
|
778
|
+
/** A customer member as returned by `addMember` / `updateMember`. */
|
|
779
|
+
interface MemberProfile {
|
|
780
|
+
id: string;
|
|
781
|
+
name: string;
|
|
782
|
+
email: string | null;
|
|
783
|
+
joinedAt: string;
|
|
784
|
+
}
|
|
785
|
+
/** The member removed by `removeMember` (`DELETE .../members/:memberId`). */
|
|
786
|
+
interface RemovedMember {
|
|
787
|
+
name: string;
|
|
788
|
+
email: string | null;
|
|
789
|
+
}
|
|
718
790
|
interface AddMemberInput {
|
|
719
791
|
name: string;
|
|
720
|
-
|
|
792
|
+
/** Must be unique (case-insensitively) among the customer's active members. */
|
|
721
793
|
email?: string;
|
|
722
|
-
employeeId?: string;
|
|
723
|
-
phone?: string;
|
|
724
794
|
}
|
|
725
|
-
/** Role is fixed after creation; omit it here. */
|
|
726
795
|
interface UpdateMemberInput {
|
|
727
796
|
name: string;
|
|
797
|
+
/** Must be unique (case-insensitively) among the customer's active members. */
|
|
728
798
|
email?: string;
|
|
729
|
-
employeeId?: string;
|
|
730
|
-
phone?: string;
|
|
731
799
|
}
|
|
732
800
|
type WalletTransactionType = "CREDIT" | "DEBIT";
|
|
733
801
|
interface WalletTransaction {
|
|
@@ -1023,6 +1091,160 @@ interface UnitInput {
|
|
|
1023
1091
|
customerId: string;
|
|
1024
1092
|
agentKey: string;
|
|
1025
1093
|
member?: string;
|
|
1094
|
+
/**
|
|
1095
|
+
* How many units this one report covers. Defaults to 1 server-side, so a
|
|
1096
|
+
* caller reporting one unit per call simply omits it. Whole numbers, at most
|
|
1097
|
+
* 1,000,000 per call.
|
|
1098
|
+
*
|
|
1099
|
+
* On an ADVANCE (prepaid) plan the draw is all-or-nothing: asking for more
|
|
1100
|
+
* than remains is refused IN FULL rather than partially filled.
|
|
1101
|
+
*/
|
|
1102
|
+
quantity?: number;
|
|
1103
|
+
/** Optional composite this unit report belongs to. See {@link CompositeTag}. */
|
|
1104
|
+
composite?: CompositeTag;
|
|
1105
|
+
/**
|
|
1106
|
+
* Idempotency key for safe retries — a repeat carrying the same key returns
|
|
1107
|
+
* the original result instead of drawing the balance down twice.
|
|
1108
|
+
*
|
|
1109
|
+
* New in the `/api/v1/signal/unit` route: the legacy `/api/v1/units` had no
|
|
1110
|
+
* idempotency at all, so a retried unit report double-charged.
|
|
1111
|
+
*
|
|
1112
|
+
* **Auto-generated (UUID v4) if omitted** and reused across every retry of
|
|
1113
|
+
* this call, exactly like a signal's. That matters more here than it looks:
|
|
1114
|
+
* unit reports opt into transport retries, so without a key one 500-then-200
|
|
1115
|
+
* is two distinct billable reports.
|
|
1116
|
+
*
|
|
1117
|
+
* Supply your own — a stable id for this logical event — to also dedup
|
|
1118
|
+
* across process restarts or at-least-once redelivery, which an in-memory
|
|
1119
|
+
* auto key cannot survive.
|
|
1120
|
+
*/
|
|
1121
|
+
idempotencyKey?: string;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* The result of `signals.unit()`.
|
|
1125
|
+
*
|
|
1126
|
+
* Shaped like {@link TrackResult} and for the same reason: `/api/v1/signal/unit`
|
|
1127
|
+
* is durable, so it answers `202` with no priced event when the server hands
|
|
1128
|
+
* the report to its queue, and `200` with `unitUsage` when it prices inline.
|
|
1129
|
+
* The legacy `/api/v1/units` always priced inline, which is why this used to be
|
|
1130
|
+
* a bare `{ unitUsage }`. Branch on `queued`; never assume `unitUsage`.
|
|
1131
|
+
*/
|
|
1132
|
+
interface UnitTrackResult {
|
|
1133
|
+
/** True when the report was accepted but not yet priced (`202`). */
|
|
1134
|
+
queued: boolean;
|
|
1135
|
+
/** The priced unit event. Non-null ONLY when the server priced inline. */
|
|
1136
|
+
unitUsage?: SerializedUnitUsage | null;
|
|
1137
|
+
/** The durable-queue message id, present only on a `202`. */
|
|
1138
|
+
messageId?: string;
|
|
1139
|
+
/** The durable inbox id — see {@link TrackResult.rawId}. */
|
|
1140
|
+
rawId?: string;
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Input for `signals.completeComposite()` — closes ONE occurrence of a
|
|
1144
|
+
* composite, which is the moment it is billed.
|
|
1145
|
+
*/
|
|
1146
|
+
interface CompositeCompletionInput {
|
|
1147
|
+
customerId: string;
|
|
1148
|
+
/** Which occurrence to close: the composite's `refId` and the correlation
|
|
1149
|
+
* value the signals were tagged with. */
|
|
1150
|
+
composite: CompositeTag;
|
|
1151
|
+
/** Idempotency key, auto-generated if omitted. Closing twice is already a
|
|
1152
|
+
* safe no-op, so this only collapses retries into one recorded attempt
|
|
1153
|
+
* rather than protecting against a double charge. */
|
|
1154
|
+
idempotencyKey?: string;
|
|
1155
|
+
}
|
|
1156
|
+
/** One catalogue item a composite is restricted to. `agentKey` is what a
|
|
1157
|
+
* signal names, so it is the field you actually integrate against. */
|
|
1158
|
+
interface CompositeCatalogueRef {
|
|
1159
|
+
id: string;
|
|
1160
|
+
name: string;
|
|
1161
|
+
agentKey: string;
|
|
1162
|
+
}
|
|
1163
|
+
/** One composite in the org's catalogue — `cnk.composites.list()`. */
|
|
1164
|
+
interface Composite {
|
|
1165
|
+
id: string;
|
|
1166
|
+
name: string;
|
|
1167
|
+
/** The stable identifier you put in a signal's `composite` block as `ref`. */
|
|
1168
|
+
refId: string;
|
|
1169
|
+
description: string | null;
|
|
1170
|
+
/** USD charged per occurrence WHEN A PLAN SELLS THIS as a composite
|
|
1171
|
+
* component (`quantity × price`, frozen into the purchase at buy time). The
|
|
1172
|
+
* catalogue row alone bills nothing. */
|
|
1173
|
+
price: number;
|
|
1174
|
+
/** False once archived. An archived composite stops NEW signals resolving to
|
|
1175
|
+
* it but keeps every row it already owns. */
|
|
1176
|
+
isActive: boolean;
|
|
1177
|
+
createdAt: string;
|
|
1178
|
+
/**
|
|
1179
|
+
* The credits / outcomes / units this composite is restricted to — only
|
|
1180
|
+
* signals naming one of these may carry its tag.
|
|
1181
|
+
*
|
|
1182
|
+
* All three lists empty means UNRESTRICTED (it accepts any of the org's
|
|
1183
|
+
* traffic under this tag). Nothing created through the API can be
|
|
1184
|
+
* unrestricted, but rows predating that rule exist — so don't assume
|
|
1185
|
+
* non-empty.
|
|
1186
|
+
*/
|
|
1187
|
+
entitlements: {
|
|
1188
|
+
credits: CompositeCatalogueRef[];
|
|
1189
|
+
outcomes: CompositeCatalogueRef[];
|
|
1190
|
+
units: CompositeCatalogueRef[];
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
/** Input for `cnk.composites.create()`. */
|
|
1194
|
+
interface CreateCompositeInput {
|
|
1195
|
+
name: string;
|
|
1196
|
+
/**
|
|
1197
|
+
* The tag identifier. Lowercased, and restricted to the same characters as
|
|
1198
|
+
* an `agentKey` — but validated harder than one, because it may not collide
|
|
1199
|
+
* with a field the ingest schemas already own (`customerId`, `usage`,
|
|
1200
|
+
* `agentKey`, `runId`, `member`, `custom`, `composite`, …). A colliding
|
|
1201
|
+
* `refId` is refused at create time rather than silently ignored at ingest.
|
|
1202
|
+
*/
|
|
1203
|
+
refId: string;
|
|
1204
|
+
/** USD per occurrence once a plan sells it. Required — an unpriced composite
|
|
1205
|
+
* put on a plan would bill 0, which is a money bug that is hard to see. */
|
|
1206
|
+
price: number;
|
|
1207
|
+
description?: string | null;
|
|
1208
|
+
/**
|
|
1209
|
+
* What the composite wraps. At least one id across the three lists is
|
|
1210
|
+
* REQUIRED: a composite restricted to nothing would accept every signal in
|
|
1211
|
+
* the org. Get the ids from `credits.list()`, `outcomes.list()` and
|
|
1212
|
+
* `units.list()`.
|
|
1213
|
+
*/
|
|
1214
|
+
entitlements: {
|
|
1215
|
+
creditIds?: string[];
|
|
1216
|
+
outcomeIds?: string[];
|
|
1217
|
+
unitIds?: string[];
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* The result of `signals.completeComposite()`.
|
|
1222
|
+
*
|
|
1223
|
+
* `status` distinguishes the first close from a replay. Note that an EARLY
|
|
1224
|
+
* ping — one sent before every credit / outcome / unit the composite is
|
|
1225
|
+
* restricted to has reported under the same value — is not an error: the
|
|
1226
|
+
* server parks it and completes it automatically when the missing signal
|
|
1227
|
+
* lands. That case answers with no `status`, only a `rawId` to follow.
|
|
1228
|
+
*/
|
|
1229
|
+
interface CompositeCompletionResult {
|
|
1230
|
+
/** True when the ping was accepted but not yet applied (`202`). */
|
|
1231
|
+
queued: boolean;
|
|
1232
|
+
/** `COMPLETED` on the first close, `ALREADY_COMPLETED` on a replay. Absent
|
|
1233
|
+
* when the ping was queued or parked. */
|
|
1234
|
+
status?: "COMPLETED" | "ALREADY_COMPLETED";
|
|
1235
|
+
/** The composite that was closed. Null on the replay of a historical row
|
|
1236
|
+
* whose occurrence can no longer be read back. */
|
|
1237
|
+
composite?: {
|
|
1238
|
+
id: string;
|
|
1239
|
+
name: string;
|
|
1240
|
+
refId: string;
|
|
1241
|
+
} | null;
|
|
1242
|
+
/** The correlation value whose occurrence was closed. */
|
|
1243
|
+
value?: string | null;
|
|
1244
|
+
/** The durable-queue message id, present only on a `202`. */
|
|
1245
|
+
messageId?: string;
|
|
1246
|
+
/** The durable inbox id — see {@link TrackResult.rawId}. */
|
|
1247
|
+
rawId?: string;
|
|
1026
1248
|
}
|
|
1027
1249
|
/** One serialized unit-consumption event — the result of `signals.unit()` and
|
|
1028
1250
|
* each element of `UnitUsageList.events`. */
|
|
@@ -1185,6 +1407,35 @@ declare class Transport {
|
|
|
1185
1407
|
private buildUrl;
|
|
1186
1408
|
}
|
|
1187
1409
|
|
|
1410
|
+
/**
|
|
1411
|
+
* The `composites` resource — manage the org's composite *catalogue*: the
|
|
1412
|
+
* bundles of credits / outcomes / units that are grouped under one tag and
|
|
1413
|
+
* sold on a plan as a single thing. `/api/v1/composites`.
|
|
1414
|
+
*
|
|
1415
|
+
* Two things live elsewhere, deliberately:
|
|
1416
|
+
* • Tagging a signal into a composite occurrence is `composite: { ref, value }`
|
|
1417
|
+
* on the signal itself (see `signals.credit()` / `.outcome()` / `.unit()`).
|
|
1418
|
+
* • Closing an occurrence — the moment it is billed — is
|
|
1419
|
+
* `signals.completeComposite()`.
|
|
1420
|
+
*
|
|
1421
|
+
* This resource only defines what composites EXIST. Creating one prices it but
|
|
1422
|
+
* charges nobody: an invoice is built from plan components, never from a
|
|
1423
|
+
* catalogue entry, so a composite starts costing money only once a plan sells
|
|
1424
|
+
* it (`quantity × price`, frozen into the purchase at buy time).
|
|
1425
|
+
*/
|
|
1426
|
+
declare class Composites {
|
|
1427
|
+
private readonly transport;
|
|
1428
|
+
constructor(transport: Transport);
|
|
1429
|
+
/** List composites. Pass `{ active: true }` for only the ones a signal can
|
|
1430
|
+
* still be tagged with — the default list INCLUDES archived ones, which
|
|
1431
|
+
* keep every row they already own. */
|
|
1432
|
+
list(params?: {
|
|
1433
|
+
active?: boolean;
|
|
1434
|
+
}): Promise<Composite[]>;
|
|
1435
|
+
/** Create a composite. `POST /api/v1/composites`. */
|
|
1436
|
+
create(input: CreateCompositeInput): Promise<Composite>;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1188
1439
|
/**
|
|
1189
1440
|
* The `credits` resource — manage the org's credit *types* (the catalog). A
|
|
1190
1441
|
* credit's stable `agentKey` is what you pass to `signals.credit()` when
|
|
@@ -1275,12 +1526,12 @@ declare class Customers {
|
|
|
1275
1526
|
plan(id: string): Promise<CustomerPlan>;
|
|
1276
1527
|
/** List a customer's members. `GET …/:id/members`. */
|
|
1277
1528
|
listMembers(id: string): Promise<Member[]>;
|
|
1278
|
-
/** Add a member to a customer. Duplicate `
|
|
1279
|
-
addMember(id: string, input: AddMemberInput): Promise<
|
|
1280
|
-
/** Update a member's profile
|
|
1281
|
-
updateMember(id: string, memberId: string, input: UpdateMemberInput): Promise<
|
|
1282
|
-
/** Remove a member from a customer. `DELETE …/:id/members/:memberId`. */
|
|
1283
|
-
removeMember(id: string, memberId: string): Promise<
|
|
1529
|
+
/** Add a member to a customer. Duplicate `email` → ConflictError. */
|
|
1530
|
+
addMember(id: string, input: AddMemberInput): Promise<MemberProfile>;
|
|
1531
|
+
/** Update a member's profile. Duplicate `email` → ConflictError. `PATCH …/:id/members/:memberId`. */
|
|
1532
|
+
updateMember(id: string, memberId: string, input: UpdateMemberInput): Promise<MemberProfile>;
|
|
1533
|
+
/** Remove a member from a customer, returning who was removed. `DELETE …/:id/members/:memberId`. */
|
|
1534
|
+
removeMember(id: string, memberId: string): Promise<RemovedMember>;
|
|
1284
1535
|
/** The customer's wallet balance + transactions. `GET …/:id/wallet`. */
|
|
1285
1536
|
wallet(id: string, params?: {
|
|
1286
1537
|
limit?: number;
|
|
@@ -1443,7 +1694,17 @@ declare class Purchases {
|
|
|
1443
1694
|
|
|
1444
1695
|
/** One buffered, wire-ready signal awaiting a background flush. */
|
|
1445
1696
|
interface QueuedSignal {
|
|
1446
|
-
/**
|
|
1697
|
+
/**
|
|
1698
|
+
* The route this signal posts to (`/api/v1/signal/credit` etc.), decided by
|
|
1699
|
+
* `track()` when the signal was buffered.
|
|
1700
|
+
*
|
|
1701
|
+
* It is stored per item rather than fixed on the Flusher because each meter
|
|
1702
|
+
* now has its own endpoint. A single hardcoded path was fine when everything
|
|
1703
|
+
* went to `/api/v1/usage`; keeping one would have meant async mode silently
|
|
1704
|
+
* posting to the deprecated route while sync mode used the new ones.
|
|
1705
|
+
*/
|
|
1706
|
+
path: string;
|
|
1707
|
+
/** The exact JSON body to POST. */
|
|
1447
1708
|
body: Record<string, unknown>;
|
|
1448
1709
|
/** The original signal — passed to onError/onDrop hooks. */
|
|
1449
1710
|
signal: Signal;
|
|
@@ -1482,7 +1743,23 @@ declare class Flusher {
|
|
|
1482
1743
|
close(): Promise<void>;
|
|
1483
1744
|
}
|
|
1484
1745
|
|
|
1485
|
-
/**
|
|
1746
|
+
/**
|
|
1747
|
+
* Builds the request body for a typed Signal.
|
|
1748
|
+
*
|
|
1749
|
+
* Two grouping changes from the pre-0.10 `POST /api/v1/usage` body, both of
|
|
1750
|
+
* which the server now requires:
|
|
1751
|
+
*
|
|
1752
|
+
* usage: { model, inputTokens, outputTokens, cacheTokens }
|
|
1753
|
+
* composite: { "<refId>": "<value>" }
|
|
1754
|
+
*
|
|
1755
|
+
* `usage` collects the four fields describing one LLM call. `composite` is the
|
|
1756
|
+
* more consequential one: the tag used to sit at the TOP LEVEL under its own
|
|
1757
|
+
* caller-defined property name, which meant a composite called `model` or
|
|
1758
|
+
* `status` shadowed a real ingest field. Nested, the two namespaces are
|
|
1759
|
+
* separate and that collision is impossible.
|
|
1760
|
+
*
|
|
1761
|
+
* The route is NOT part of this body — see {@link SIGNAL_PATHS}.
|
|
1762
|
+
*/
|
|
1486
1763
|
declare function signalToWire(signal: Signal): Record<string, unknown>;
|
|
1487
1764
|
/**
|
|
1488
1765
|
* The `signals` resource: record usage signals and read them back.
|
|
@@ -1491,12 +1768,13 @@ declare function signalToWire(signal: Signal): Record<string, unknown>;
|
|
|
1491
1768
|
* immediately with `{ queued: true }`. Pass `{ wait: true }` (or construct the
|
|
1492
1769
|
* client in `sync` mode) to await the request.
|
|
1493
1770
|
*
|
|
1494
|
-
* Awaiting the request does NOT guarantee a priced result.
|
|
1495
|
-
*
|
|
1496
|
-
*
|
|
1497
|
-
*
|
|
1498
|
-
*
|
|
1499
|
-
* `
|
|
1771
|
+
* Awaiting the request does NOT guarantee a priced result. The server writes
|
|
1772
|
+
* every signal to a durable inbox and then hands it to a worker, so it answers
|
|
1773
|
+
* `202` and `track()` resolves `{ queued: true, messageId, rawId, usageLog:
|
|
1774
|
+
* null }` — accepted and impossible to lose, but not yet billed. Only when the
|
|
1775
|
+
* server prices inline do you get `{ queued: false, usageLog }`. Branch on
|
|
1776
|
+
* `queued`; never assume `usageLog`.
|
|
1777
|
+
*
|
|
1500
1778
|
* `verify()` is the way to validate and price a signal synchronously, and
|
|
1501
1779
|
* `list()` is how you confirm one actually landed.
|
|
1502
1780
|
*/
|
|
@@ -1506,7 +1784,8 @@ declare class Signals {
|
|
|
1506
1784
|
private readonly cfg;
|
|
1507
1785
|
constructor(transport: Transport, flusher: Flusher, cfg: ResolvedConfig);
|
|
1508
1786
|
/**
|
|
1509
|
-
* Record one usage signal
|
|
1787
|
+
* Record one usage signal, to the route its `type` selects:
|
|
1788
|
+
* `POST /api/v1/signal/credit` | `/signal/outcome` | `/signal/wallet`.
|
|
1510
1789
|
*
|
|
1511
1790
|
* Returns as soon as the signal is buffered (async mode) or the request has
|
|
1512
1791
|
* been answered (`{ wait: true }` / sync mode). See {@link TrackResult}: a
|
|
@@ -1519,21 +1798,34 @@ declare class Signals {
|
|
|
1519
1798
|
* Validate + price a signal WITHOUT recording it (server `dryRun`). Returns
|
|
1520
1799
|
* the projected usage log so an integration can preflight before sending real
|
|
1521
1800
|
* traffic — no inbox row, wallet / outcome writes, or webhooks fire.
|
|
1801
|
+
*
|
|
1802
|
+
* Only the model-priced kinds support this. A dry run is not offered for unit
|
|
1803
|
+
* reports or composite completions, and the server REJECTS the flag on those
|
|
1804
|
+
* routes rather than accepting and ignoring it — which is why there is no
|
|
1805
|
+
* dry-run path through `unit()` or `completeComposite()`.
|
|
1522
1806
|
*/
|
|
1523
1807
|
verify(signal: Signal): Promise<SerializedUsageLog | null>;
|
|
1524
|
-
/** Meter a named credit. */
|
|
1808
|
+
/** Meter a named credit. `POST /api/v1/signal/credit`. */
|
|
1525
1809
|
credit(input: CreditInput, opts?: {
|
|
1526
1810
|
wait?: boolean;
|
|
1527
1811
|
}): Promise<TrackResult>;
|
|
1528
|
-
/** Debit the customer's wallet at model cost. */
|
|
1812
|
+
/** Debit the customer's wallet at model cost. `POST /api/v1/signal/wallet`. */
|
|
1529
1813
|
wallet(input: WalletInput, opts?: {
|
|
1530
1814
|
wait?: boolean;
|
|
1531
1815
|
}): Promise<TrackResult>;
|
|
1532
|
-
/** Advance one step of an outcome workflow. */
|
|
1816
|
+
/** Advance one step of an outcome workflow. `POST /api/v1/signal/outcome`. */
|
|
1533
1817
|
outcome(input: OutcomeInput, opts?: {
|
|
1534
1818
|
wait?: boolean;
|
|
1535
1819
|
}): Promise<TrackResult>;
|
|
1536
|
-
/**
|
|
1820
|
+
/**
|
|
1821
|
+
* Recent usage logs + totals for a customer. `GET /api/v1/usage`.
|
|
1822
|
+
*
|
|
1823
|
+
* Still the legacy path, deliberately. The `/api/v1/signal/*` family is
|
|
1824
|
+
* POST-only — it replaced how usage is INGESTED, not how it is read — so
|
|
1825
|
+
* `GET /api/v1/usage` has no successor and is not deprecated. It is also the
|
|
1826
|
+
* only way to prove a signal landed, which matters more now that ingestion
|
|
1827
|
+
* answers `202` for everything.
|
|
1828
|
+
*/
|
|
1537
1829
|
list(params: {
|
|
1538
1830
|
customerId: string;
|
|
1539
1831
|
limit?: number;
|
|
@@ -1541,12 +1833,44 @@ declare class Signals {
|
|
|
1541
1833
|
/**
|
|
1542
1834
|
* Record one unit-metered event (a fixed-price meter with no tokens),
|
|
1543
1835
|
* addressed to a catalog unit by its `agentKey`. Sent immediately — unit
|
|
1544
|
-
* events are not buffered. `POST /api/v1/
|
|
1836
|
+
* events are not buffered. `POST /api/v1/signal/unit`.
|
|
1837
|
+
*
|
|
1838
|
+
* Two things changed with the move off `POST /api/v1/units`, and both show up
|
|
1839
|
+
* in the return type. The route is now durable (the report lands in an inbox
|
|
1840
|
+
* before it is priced, so a failure parks as Pending and can be retried
|
|
1841
|
+
* instead of losing a billable event) and it answers `202` when it queues —
|
|
1842
|
+
* so this resolves {@link UnitTrackResult}, not a bare `{ unitUsage }`.
|
|
1843
|
+
* Branch on `queued`.
|
|
1844
|
+
*/
|
|
1845
|
+
unit(input: UnitInput): Promise<UnitTrackResult>;
|
|
1846
|
+
/**
|
|
1847
|
+
* Close ONE occurrence of a composite — a distinct tag value.
|
|
1848
|
+
* `POST /api/v1/signal/composite/complete`.
|
|
1849
|
+
*
|
|
1850
|
+
* A composite bundles several credits / outcomes / units and is billed as one
|
|
1851
|
+
* thing. The occurrence opens on the first tagged signal and costs nothing;
|
|
1852
|
+
* this call is the moment it is billed. Only your code knows when the
|
|
1853
|
+
* workflow ended, so this is a DECLARATION, not a hint: tagged signals may
|
|
1854
|
+
* arrive in any order and the occurrence stays open and unbilled until you
|
|
1855
|
+
* say otherwise. Put it on the line before your own `return`.
|
|
1856
|
+
*
|
|
1857
|
+
* An OUTCOME never needs this — its own `complete: true` closes its run and
|
|
1858
|
+
* the matching occurrence together. Credits and units have no "done" signal
|
|
1859
|
+
* of their own, so this is theirs.
|
|
1860
|
+
*
|
|
1861
|
+
* Closing twice is safe: the second call answers `ALREADY_COMPLETED` and
|
|
1862
|
+
* cannot bill again. Calling it EARLY is also safe — before every entitlement
|
|
1863
|
+
* the composite is restricted to has reported, or while an ADVANCE pool is
|
|
1864
|
+
* full — the server parks the ping and applies it when the blocker clears,
|
|
1865
|
+
* rather than failing it.
|
|
1866
|
+
*/
|
|
1867
|
+
completeComposite(input: CompositeCompletionInput): Promise<CompositeCompletionResult>;
|
|
1868
|
+
/**
|
|
1869
|
+
* A customer's unit balances + recent unit events. `GET /api/v1/units`.
|
|
1870
|
+
*
|
|
1871
|
+
* Legacy path for the same reason as {@link list}: the signal family is
|
|
1872
|
+
* POST-only, so the read side has no successor and is not deprecated.
|
|
1545
1873
|
*/
|
|
1546
|
-
unit(input: UnitInput): Promise<{
|
|
1547
|
-
unitUsage: SerializedUnitUsage;
|
|
1548
|
-
}>;
|
|
1549
|
-
/** A customer's unit balances + recent unit events. `GET /api/v1/units`. */
|
|
1550
1874
|
unitUsage(params: {
|
|
1551
1875
|
customerId: string;
|
|
1552
1876
|
limit?: number;
|
|
@@ -1641,6 +1965,8 @@ declare class ClockNext {
|
|
|
1641
1965
|
readonly payments: Payments;
|
|
1642
1966
|
/** Manage the credit-type catalog. */
|
|
1643
1967
|
readonly credits: Credits;
|
|
1968
|
+
/** Manage the composite catalog — bundles billed as one thing. */
|
|
1969
|
+
readonly composites: Composites;
|
|
1644
1970
|
/** Manage the outcome-type catalog. */
|
|
1645
1971
|
readonly outcomes: Outcomes;
|
|
1646
1972
|
/** Manage the unit-type catalog. */
|
|
@@ -1711,4 +2037,4 @@ declare class NetworkError extends ClockNextError {
|
|
|
1711
2037
|
constructor(message: string);
|
|
1712
2038
|
}
|
|
1713
2039
|
|
|
1714
|
-
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
|
|
2040
|
+
export { type AddMemberInput, AllowanceError, type ApiCustomer, AuthError, type BillingCycle, type BillingMode, ClockNext, type ClockNextConfig, ClockNextError, type ComponentType, type Composite, type CompositeCatalogueRef, type CompositeCompletionInput, type CompositeCompletionResult, type CompositeComponentInput, type CompositeTag, ConflictError, type CostPoint, type CostStats, type CreateCompositeInput, 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 MemberProfile, 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 RemovedMember, 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 UnitTrackResult, 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 };
|