@clocknext/sdk 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,17 +46,37 @@ A signal is silently discarded if any of these is true:
46
46
  | a required field is missing | see the tables below |
47
47
  | the allowance is exhausted | top up with `customers.adjustCredit()` etc. |
48
48
 
49
- Two things follow:
50
-
51
- - **Always pass `onError`.** It is the only channel a rejected signal has. The
52
- SDK logs to `console.error` by default rather than staying silent, but a real
53
- integration should handle it.
54
- - **Prove it landed with `signals.list()`**, not with the return value. That is
55
- the only authoritative read.
49
+ Three things follow.
50
+
51
+ **The per-signal verdict lives in the ClockNext dashboard, and only there.**
52
+ Every signal is logged with its outcome — accepted, processed, or failed with a
53
+ reason — on the workspace's signal log. That view is owner-only in the product
54
+ UI by design and is not exposed through this SDK or any API. When usage is not
55
+ being billed and the causes below do not explain it, that log is where you look.
56
+
57
+ **`onError` does not see worker-side rejections.** It fires when the HTTP
58
+ request itself fails — network, timeout, auth, a `4xx` returned *before* the
59
+ `202`. A signal that was accepted and then rejected during pricing never
60
+ reaches it, because from the SDK's point of view that request succeeded. Pass it
61
+ anyway: it is how you catch a bad API key, an unreachable host, and a dropped
62
+ buffer.
63
+
64
+ **`signals.list()` is the programmatic check, and it is partial.** It returns
65
+ priced usage logs, each with a `status`, so it can tell you a signal landed and
66
+ whether pricing succeeded. It cannot tell you about a signal that was rejected
67
+ *before* it was ever priced — an unknown `agentKey`, a customer with no plan —
68
+ because no usage log is written for one. Those appear only in the dashboard.
56
69
 
57
70
  ```ts
58
71
  const usage = await cnk.signals.list({ customerId });
59
- console.log(usage.totals.count); // 0 means nothing was recorded
72
+
73
+ // Nothing here at all → rejected before pricing. Check the dashboard's log.
74
+ console.log(usage.totals.count);
75
+
76
+ // Present but not billed → priced and refused; `status` says which.
77
+ for (const log of usage.logs) {
78
+ if (log.status !== "SUCCESS") console.warn(log.id, log.status);
79
+ }
60
80
  ```
61
81
 
62
82
  ### 2. Nothing can be metered until five things exist
@@ -103,7 +123,8 @@ if (!apiKey) throw new Error("CLOCKNEXT_API_KEY is required");
103
123
 
104
124
  const cnk = new ClockNext({
105
125
  apiKey,
106
- // The only channel a rejected signal has. Do not skip it.
126
+ // Catches request-level failures (bad key, network, dropped buffer).
127
+ // Rejections found later, during pricing, are visible only in the dashboard.
107
128
  onError: (error, signal) =>
108
129
  console.error("[clocknext] signal rejected", signal?.type, error),
109
130
  });
@@ -430,7 +451,13 @@ and `.idempotencyKey` on metering calls. Constructor failures — a missing
430
451
 
431
452
  Because ingest answers `202` before validating, **a try/catch around
432
453
  `signals.credit()` will not catch a rejected signal**, with or without
433
- `{ wait: true }`. Those surface on the hooks:
454
+ `{ wait: true }` — and neither will `onError`. A rejection discovered during
455
+ pricing has no programmatic channel at all; it is recorded on the workspace's
456
+ signal log in the ClockNext dashboard, which is owner-only by design.
457
+
458
+ What the hooks below DO cover is everything that fails before the `202`: an
459
+ invalid API key, an unreachable host, a timeout, and signals the SDK dropped
460
+ without sending.
434
461
 
435
462
  ```ts
436
463
  import { ClockNext, ClockNextError } from "@clocknext/sdk";
@@ -452,6 +479,10 @@ const cnk = new ClockNext({
452
479
 
453
480
  `onFlush` counts signals the server **accepted**, not signals it billed.
454
481
 
482
+ So the division of labour is: these hooks tell you your integration cannot
483
+ reach ClockNext; `signals.list()` tells you what got priced; the dashboard's
484
+ signal log tells you why an individual signal did not.
485
+
455
486
  ## Balances and usage
456
487
 
457
488
  ```ts
package/dist/index.cjs CHANGED
@@ -328,7 +328,7 @@ function sleep(ms) {
328
328
  }
329
329
 
330
330
  // src/http.ts
331
- var SDK_VERSION = "0.12.0" ;
331
+ var SDK_VERSION = "0.12.1" ;
332
332
  var Transport = class {
333
333
  constructor(cfg) {
334
334
  this.cfg = cfg;