@garuhq/node 1.1.0 → 3.0.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/CHANGELOG.md CHANGED
@@ -3,6 +3,94 @@
3
3
  All notable changes to `@garuhq/node` are documented in this file. Format:
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning: [SemVer](https://semver.org/).
5
5
 
6
+ ## [3.0.0] — 2026-08-22
7
+
8
+ **Breaking:** `webhookEvents` now targets the versioned public API
9
+ `/api/v1/webhook-events`, keyed on `uuid`. If you use `garu.webhookEvents.*`,
10
+ read the migration below.
11
+
12
+ ### Breaking
13
+
14
+ - **`webhookEvents` moved to `/api/v1/webhook-events`** and an event is
15
+ keyed by **`uuid`**, not a numeric `id`.
16
+ - `webhookEvents.get(id: number)` → **`webhookEvents.get(uuid: string)`**.
17
+ - `webhookEvents.retry(id)` / `webhookEvents.resend(id, params?)` — same
18
+ signature shape, but the id argument is now the `uuid`.
19
+ - `WebhookEvent.id` is **removed**; there is no numeric id in the public
20
+ shape. Use `WebhookEvent.uuid` everywhere. `WebhookEvent.endpointId` is
21
+ also removed — read `webhookEndpoint.id` instead (endpoint configuration
22
+ stays numeric; it did not move to `/api/v1`).
23
+ - `WebhookEvent.manualResendOf` is now a **`uuid` string** (was a numeric
24
+ id), pointing at the source event's `uuid`.
25
+ - **`webhookEvents.list()` returns `{ data, count, totalCount, totalPages }`**
26
+ (was `{ data, meta }`).
27
+ - The gateway's outbound `Idempotency-Key` for `/resend` clones is now
28
+ `resend_<uuid>` (was `resend_<numeric id>`), to match the public
29
+ identifier the SDK/CLI/MCP now expose.
30
+
31
+ ### Migration
32
+
33
+ ```ts
34
+ // before (0.x – 2.x)
35
+ const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
36
+ const event = failed.data[0];
37
+ event.id; // number
38
+ const clone = await garu.webhookEvents.resend(event.id);
39
+ clone.manualResendOf === event.id; // true
40
+
41
+ // after (3.0.0)
42
+ const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
43
+ const event = failed.data[0];
44
+ event.uuid; // string
45
+ const clone = await garu.webhookEvents.resend(event.uuid);
46
+ clone.manualResendOf === event.uuid; // true
47
+ ```
48
+
49
+ ## [2.0.0] — 2026-08-22
50
+
51
+ **Breaking:** `customers` now targets the versioned public API `/api/v1/customers`,
52
+ keyed on `uuid`. If you use `garu.customers.*`, read the migration below.
53
+
54
+ ### Breaking
55
+
56
+ - **`customers` moved to `/api/v1/customers`** and a customer is keyed by
57
+ **`uuid`**, not a numeric `id`.
58
+ - `customers.get(id: number)` → **`customers.get(uuid: string)`** (name
59
+ unchanged, param type changed).
60
+ - `customers.update(id, params)` — same signature shape, but the id
61
+ argument is now the `uuid`, and the request now goes out as `PATCH`
62
+ (was `PUT`).
63
+ - `customers.setBillingEmailOverride(id, params)` / `customers.delete(id)`
64
+ — same, `id` → `uuid`.
65
+ - `CustomerRecord.id` is **removed**; there is no numeric id in the public
66
+ shape. Use `CustomerRecord.uuid` everywhere.
67
+ - **`customers.delete()` now resolves `{ removed: boolean }`** (was `void`).
68
+ - **`customers.list()` returns `{ data, count, totalCount, totalPages }`**
69
+ (was `{ data, meta }`).
70
+ - `installmentPlans.create` and `scheduledCharges.create` are **not**
71
+ migrated yet — they still take a numeric `customerId`. Fetch that id from
72
+ the dashboard or the internal `/api/customers` endpoint until those two
73
+ resources move to `/api/v1` too (tracked in `SPEC-public-api-v1.md` §9
74
+ Phase 4 on the `gateway` repo).
75
+
76
+ ### Migration
77
+
78
+ ```ts
79
+ // before (1.x)
80
+ const c = await garu.customers.create({ name, email, document, phone, personType });
81
+ c.id; // number
82
+ const one = await garu.customers.get(c.id);
83
+ await garu.customers.update(c.id, { name: 'Maria Santos' });
84
+ await garu.customers.delete(c.id);
85
+
86
+ // after (2.0.0)
87
+ const c = await garu.customers.create({ name, email, document, phone, personType });
88
+ c.uuid; // string
89
+ const one = await garu.customers.get(c.uuid);
90
+ await garu.customers.update(c.uuid, { name: 'Maria Santos' });
91
+ const { removed } = await garu.customers.delete(c.uuid);
92
+ ```
93
+
6
94
  ## [1.1.0] — 2026-08-15
7
95
 
8
96
 
package/README.md CHANGED
@@ -84,13 +84,13 @@ const garu = new Garu({
84
84
 
85
85
  ## Charges
86
86
 
87
- | Method | Description |
88
- | ----------------------- | --------------------------------------------- |
89
- | `create(params)` | Create a PIX, credit-card, or boleto charge. |
90
- | `retrieve(uuid)` | Fetch a single charge by uuid. |
91
- | `list(params?)` | List charges with pagination and filters. |
92
- | `refund(uuid, params?)` | Refund a charge fully or partially (reais). |
93
- | `cancel(uuid)` | Cancel an unpaid charge. |
87
+ | Method | Description |
88
+ | ----------------------- | -------------------------------------------- |
89
+ | `create(params)` | Create a PIX, credit-card, or boleto charge. |
90
+ | `retrieve(uuid)` | Fetch a single charge by uuid. |
91
+ | `list(params?)` | List charges with pagination and filters. |
92
+ | `refund(uuid, params?)` | Refund a charge fully or partially (reais). |
93
+ | `cancel(uuid)` | Cancel an unpaid charge. |
94
94
 
95
95
  ### Create a PIX charge
96
96
 
@@ -146,13 +146,20 @@ await garu.charges.refund('6f1c9b2e-…', { amount: 10.0 }); // partial refund (
146
146
 
147
147
  ## Customers
148
148
 
149
- | Method | Description |
150
- | -------------------- | ------------------------------------------ |
151
- | `create(params)` | Create a new customer. |
152
- | `list(params?)` | List customers with pagination and search. |
153
- | `get(id)` | Fetch a single customer by ID. |
154
- | `update(id, params)` | Update a customer's profile. |
155
- | `delete(id)` | Delete a customer. |
149
+ Backed by `/api/v1/customers`, keyed on `uuid` — there is no numeric id in
150
+ this shape. `installmentPlans.create` and `scheduledCharges.create` still
151
+ link customers by the internal numeric id (unmigrated resources); fetch that
152
+ id from the dashboard or the internal `/api/customers` endpoint until they
153
+ move to `/api/v1` too.
154
+
155
+ | Method | Description |
156
+ | --------------------------------------- | ----------------------------------------------- |
157
+ | `create(params)` | Register a customer for the current seller. |
158
+ | `list(params?)` | List customers with pagination and search. |
159
+ | `get(uuid)` | Fetch a single customer by uuid. |
160
+ | `update(uuid, params)` | Partially update a customer's profile. |
161
+ | `setBillingEmailOverride(uuid, params)` | Set or clear the sticky billing-email override. |
162
+ | `delete(uuid)` | Remove a customer from the current seller. |
156
163
 
157
164
  ```ts
158
165
  const customer = await garu.customers.create({
@@ -163,7 +170,7 @@ const customer = await garu.customers.create({
163
170
  personType: 'fisica'
164
171
  });
165
172
 
166
- const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
173
+ const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
167
174
  ```
168
175
 
169
176
  ## Products
@@ -390,18 +397,19 @@ The seller-facing delivery log for outbound webhooks. Use it to audit deliveries
390
397
  const failed = await garu.webhookEvents.list({ status: 'failed', limit: 50 });
391
398
 
392
399
  // Inspect one event end-to-end
393
- const event = await garu.webhookEvents.get(42);
394
- console.log(event.responseStatus, event.responseBody);
400
+ const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
401
+ event.responseStatus;
402
+ event.responseBody;
395
403
 
396
404
  // Audit-trail-preserving replay (recommended)
397
- const clone = await garu.webhookEvents.resend(42);
398
- clone.id !== event.id; // true — fresh row with its own id
399
- clone.manualResendOf === event.id; // true — points back at the source
405
+ const clone = await garu.webhookEvents.resend(event.uuid);
406
+ clone.uuid !== event.uuid; // true — fresh row with its own uuid
407
+ clone.manualResendOf === event.uuid; // true — points back at the source
400
408
  ```
401
409
 
402
- `resend(id)` is the audit-preserving counterpart to `retry(id)` — the backend inserts a fresh event whose `manualResendOf` points back at the source, then dispatches that clone. The original row stays exactly as it was, so the historical record of the prior failure (status, response status/body, attempts) survives. Works on any source status (`success` / `failed` / `pending`).
410
+ `resend(uuid)` is the audit-preserving counterpart to `retry(uuid)` — the backend inserts a fresh event whose `manualResendOf` points back at the source, then dispatches that clone. The original row stays exactly as it was, so the historical record of the prior failure (status, response status/body, attempts) survives. Works on any source status (`success` / `failed` / `pending`).
403
411
 
404
- Outbound deliveries of a resent event carry `Idempotency-Key: resend_<originalId>`, so recipient handlers can distinguish a resend from a fresh delivery both by the header prefix and by reading the response payload's `manualResendOf` field.
412
+ Outbound deliveries of a resent event carry `Idempotency-Key: resend_<cloneUuid>`, so recipient handlers can distinguish a resend from a fresh delivery both by the header prefix and by reading the response payload's `manualResendOf` field.
405
413
 
406
414
  > [!NOTE]
407
415
  > The SDK auto-attaches `X-Idempotency-Key` (UUIDv4) on `resend()` so transient transport retries can't create duplicate clones. Pass `{ idempotencyKey }` to dedupe across your own retry layer.
package/dist/index.cjs CHANGED
@@ -633,10 +633,11 @@ var Customers = class {
633
633
  * phone: '11987654321',
634
634
  * personType: 'fisica'
635
635
  * });
636
+ * customer.uuid;
636
637
  */
637
638
  async create(params) {
638
639
  return this.http.call(
639
- (signal) => this.http.client.POST("/api/customers", {
640
+ (signal) => this.http.client.POST("/api/v1/customers", {
640
641
  body: params,
641
642
  signal
642
643
  }).then((r) => r)
@@ -646,7 +647,11 @@ var Customers = class {
646
647
  * List customers for the authenticated seller, with pagination and search.
647
648
  *
648
649
  * @example
649
- * const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
650
+ * const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
651
+ *
652
+ * @example
653
+ * // Customers with at least one overdue scheduled charge (carnê included).
654
+ * const atRisk = await garu.customers.list({ status: 'overdue' });
650
655
  */
651
656
  async list(params = {}) {
652
657
  const query = {};
@@ -655,7 +660,7 @@ var Customers = class {
655
660
  if (params.search) query.search = params.search;
656
661
  if (params.status) query.status = params.status;
657
662
  const qs = new URLSearchParams(query).toString();
658
- const url = `/api/customers${qs ? `?${qs}` : ""}`;
663
+ const url = `/api/v1/customers${qs ? `?${qs}` : ""}`;
659
664
  return this.http.call(
660
665
  (signal) => this.http.client.GET(url, { signal }).then(
661
666
  (r) => r
@@ -663,27 +668,28 @@ var Customers = class {
663
668
  );
664
669
  }
665
670
  /**
666
- * Fetch a single customer by numeric ID.
671
+ * Fetch a single customer by uuid.
667
672
  *
668
673
  * @example
669
- * const customer = await garu.customers.get(42);
674
+ * const customer = await garu.customers.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
670
675
  */
671
- async get(id) {
676
+ async get(uuid) {
672
677
  return this.http.call(
673
- (signal) => this.http.client.GET(`/api/customers/${id}`, { signal }).then(
678
+ (signal) => this.http.client.GET(`/api/v1/customers/${uuid}`, { signal }).then(
674
679
  (r) => r
675
680
  )
676
681
  );
677
682
  }
678
683
  /**
679
- * Update a customer's profile for the current seller.
684
+ * Update a customer's profile for the current seller. Partial — only the
685
+ * fields you pass change.
680
686
  *
681
687
  * @example
682
- * const updated = await garu.customers.update(42, { name: 'Maria Santos' });
688
+ * const updated = await garu.customers.update('a1b2c3d4-...', { name: 'Maria Santos' });
683
689
  */
684
- async update(id, params) {
690
+ async update(uuid, params) {
685
691
  return this.http.call(
686
- (signal) => this.http.client.PUT(`/api/customers/${id}`, {
692
+ (signal) => this.http.client.PATCH(`/api/v1/customers/${uuid}`, {
687
693
  body: params,
688
694
  signal
689
695
  }).then((r) => r)
@@ -698,30 +704,31 @@ var Customers = class {
698
704
  *
699
705
  * @example
700
706
  * // Set
701
- * await garu.customers.setBillingEmailOverride(42, {
707
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', {
702
708
  * billingEmailOverride: 'cobrancas@empresa.com.br'
703
709
  * });
704
710
  *
705
711
  * // Clear and fall back to the last-used email
706
- * await garu.customers.setBillingEmailOverride(42, { billingEmailOverride: null });
712
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', { billingEmailOverride: null });
707
713
  */
708
- async setBillingEmailOverride(id, params) {
714
+ async setBillingEmailOverride(uuid, params) {
709
715
  return this.http.call(
710
- (signal) => this.http.client.PATCH(`/api/customers/${id}/billing-email-override`, {
716
+ (signal) => this.http.client.PATCH(`/api/v1/customers/${uuid}/billing-email-override`, {
711
717
  body: params,
712
718
  signal
713
719
  }).then((r) => r)
714
720
  );
715
721
  }
716
722
  /**
717
- * Remove a customer from the current seller.
723
+ * Remove a customer from the current seller (unlinks your profile — the
724
+ * global customer and other sellers' profiles are untouched).
718
725
  *
719
726
  * @example
720
- * await garu.customers.delete(42);
727
+ * await garu.customers.delete('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
721
728
  */
722
- async delete(id) {
723
- await this.http.call(
724
- (signal) => this.http.client.DELETE(`/api/customers/${id}`, {
729
+ async delete(uuid) {
730
+ return this.http.call(
731
+ (signal) => this.http.client.DELETE(`/api/v1/customers/${uuid}`, {
725
732
  body: {},
726
733
  signal
727
734
  }).then((r) => r)
@@ -1286,42 +1293,31 @@ var WebhookEvents = class {
1286
1293
  * });
1287
1294
  */
1288
1295
  async list(params = {}) {
1289
- const qs = new URLSearchParams();
1290
- if (params.page !== void 0) qs.set("page", String(params.page));
1291
- if (params.limit !== void 0) qs.set("limit", String(params.limit));
1292
- if (params.status) qs.set("status", params.status);
1293
- if (params.eventType) qs.set("event_type", params.eventType);
1294
- if (params.endpointId !== void 0) qs.set("endpoint_id", String(params.endpointId));
1295
- const query = qs.toString();
1296
- const url = `/api/webhook-events${query ? `?${query}` : ""}`;
1297
- const raw = await this.http.call(
1296
+ const query = {};
1297
+ if (params.page !== void 0) query.page = String(params.page);
1298
+ if (params.limit !== void 0) query.limit = String(params.limit);
1299
+ if (params.status) query.status = params.status;
1300
+ if (params.eventType) query.eventType = params.eventType;
1301
+ if (params.endpointId !== void 0) query.endpointId = String(params.endpointId);
1302
+ const qs = new URLSearchParams(query).toString();
1303
+ const url = `/api/v1/webhook-events${qs ? `?${qs}` : ""}`;
1304
+ return this.http.call(
1298
1305
  (signal) => this.http.client.GET(url, { signal }).then(
1299
1306
  (r) => r
1300
1307
  )
1301
1308
  );
1302
- return {
1303
- data: raw.events,
1304
- meta: {
1305
- page: raw.page,
1306
- limit: raw.limit,
1307
- total: raw.total,
1308
- totalPages: raw.pages
1309
- }
1310
- };
1311
1309
  }
1312
1310
  /**
1313
- * Fetch one webhook event by numeric ID — includes the full payload, the
1311
+ * Fetch one webhook event by uuid — includes the full payload, the
1314
1312
  * embedded endpoint snapshot, and the most recent response status/body.
1315
1313
  *
1316
1314
  * @example
1317
- * const event = await garu.webhookEvents.get(42);
1318
- * if (event.status === 'failed') {
1319
- * console.log(event.responseStatus, event.responseBody);
1320
- * }
1315
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1316
+ * event.status === 'failed' && event.responseStatus;
1321
1317
  */
1322
- async get(id) {
1318
+ async get(uuid) {
1323
1319
  return this.http.call(
1324
- (signal) => this.http.client.GET(`/api/webhook-events/${id}`, { signal }).then(
1320
+ (signal) => this.http.client.GET(`/api/v1/webhook-events/${uuid}`, { signal }).then(
1325
1321
  (r) => r
1326
1322
  )
1327
1323
  );
@@ -1334,28 +1330,28 @@ var WebhookEvents = class {
1334
1330
  * explicitly want the legacy in-place semantics (and for backwards
1335
1331
  * compatibility with older CLI / MCP releases).
1336
1332
  *
1337
- * Re-deliver a webhook event by ID. Resets it to `pending`, clears the
1333
+ * Re-deliver a webhook event by uuid. Resets it to `pending`, clears the
1338
1334
  * retry schedule, and triggers an immediate delivery attempt. Works on
1339
1335
  * any status (`success`, `failed`, `pending`).
1340
1336
  *
1341
1337
  * @example
1342
1338
  * const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
1343
1339
  * for (const event of failed.data) {
1344
- * await garu.webhookEvents.retry(event.id);
1340
+ * await garu.webhookEvents.retry(event.uuid);
1345
1341
  * }
1346
1342
  */
1347
- async retry(id) {
1343
+ async retry(uuid) {
1348
1344
  return this.http.call(
1349
- (signal) => this.http.client.POST(`/api/webhook-events/${id}/retry`, {
1345
+ (signal) => this.http.client.POST(`/api/v1/webhook-events/${uuid}/retry`, {
1350
1346
  body: {},
1351
1347
  signal
1352
1348
  }).then((r) => r)
1353
1349
  );
1354
1350
  }
1355
1351
  /**
1356
- * Re-deliver a webhook event by ID, audit-trail preserving. Unlike
1352
+ * Re-deliver a webhook event by uuid, audit-trail preserving. Unlike
1357
1353
  * {@link retry}, this does *not* mutate the original row — it inserts a
1358
- * fresh event (new numeric id) that points back at the source via
1354
+ * fresh event (new uuid) that points back at the source via
1359
1355
  * `manualResendOf`, then dispatches that clone. The original row is
1360
1356
  * untouched, so the historical record of the prior failure (and its
1361
1357
  * response status / body) is preserved.
@@ -1366,30 +1362,30 @@ var WebhookEvents = class {
1366
1362
  * delivery's outcome to remain on the record.
1367
1363
  *
1368
1364
  * **Outbound delivery semantics**: the gateway POSTs the clone with
1369
- * `Idempotency-Key: resend_<originalId>` (where `<originalId>` is the id
1370
- * of the source event, not the clone). Recipient handlers that key off
1365
+ * `Idempotency-Key: resend_<cloneUuid>`. Recipient handlers that key off
1371
1366
  * `Idempotency-Key` will see this as a distinct delivery from the
1372
1367
  * original — distinguishable both by the `resend_` prefix and by reading
1373
1368
  * the response payload's `manualResendOf` field.
1374
1369
  *
1375
- * **SDK→gateway dedup**: the SDK auto-attaches `X-Idempotency-Key`
1376
- * (UUIDv4 unless you pass `idempotencyKey`) so transient transport
1377
- * retries (5xx SDK backoff) cannot create duplicate clones the
1378
- * backend returns the original clone on the second call within 24h.
1370
+ * The SDK also attaches an `X-Idempotency-Key` header (UUIDv4 unless you
1371
+ * pass `idempotencyKey`); the gateway does not currently deduplicate
1372
+ * `/resend` calls against it, so retrying this call from your own code
1373
+ * after a network failure can create more than one clone — pair it with
1374
+ * your own retry-suppression if that matters for your integration.
1379
1375
  *
1380
- * Returns the *clone* event (new id), not the original. The original is
1376
+ * Returns the *clone* event (new uuid), not the original. The original is
1381
1377
  * unchanged on the server.
1382
1378
  *
1383
1379
  * @example
1384
- * const event = await garu.webhookEvents.get(42);
1385
- * const clone = await garu.webhookEvents.resend(42);
1386
- * clone.id !== event.id; // true — clone has its own id
1387
- * clone.manualResendOf === event.id; // true — points back at the source
1380
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1381
+ * const clone = await garu.webhookEvents.resend(event.uuid);
1382
+ * clone.uuid !== event.uuid; // true — clone has its own uuid
1383
+ * clone.manualResendOf === event.uuid; // true — points back at the source
1388
1384
  */
1389
- async resend(id, params = {}) {
1385
+ async resend(uuid, params = {}) {
1390
1386
  const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
1391
1387
  return this.http.call(
1392
- (signal) => this.http.client.POST(`/api/webhook-events/${id}/resend`, {
1388
+ (signal) => this.http.client.POST(`/api/v1/webhook-events/${uuid}/resend`, {
1393
1389
  body: {},
1394
1390
  headers: { "X-Idempotency-Key": idempotencyKey },
1395
1391
  signal
package/dist/index.d.cts CHANGED
@@ -261,8 +261,15 @@ interface ChargeList {
261
261
  interface CancelChargeResult {
262
262
  canceled: boolean;
263
263
  }
264
+ /**
265
+ * Public API v1 customer representation. Keyed on `uuid` — there is no
266
+ * numeric id in this shape. `installmentPlans.create` and
267
+ * `scheduledCharges.create` still link customers by the internal numeric id
268
+ * (unmigrated resources); fetch that id from the dashboard or the internal
269
+ * `/api/customers` endpoint until they move to `/api/v1` too.
270
+ */
264
271
  interface CustomerRecord {
265
- id: number;
272
+ uuid: string;
266
273
  name: string;
267
274
  email: string;
268
275
  document: string;
@@ -281,10 +288,9 @@ interface CustomerRecord {
281
288
  * Resolved billing email used for outbound seller→customer emails:
282
289
  * `billingEmailOverride ?? per-seller email ?? customer.email`.
283
290
  */
284
- billingEmail?: string;
291
+ billingEmail: string;
285
292
  /** True when a sticky `billingEmailOverride` is set for this seller. */
286
- hasBillingEmailOverride?: boolean;
287
- [key: string]: unknown;
293
+ hasBillingEmailOverride: boolean;
288
294
  }
289
295
  interface SetBillingEmailOverrideParams {
290
296
  /**
@@ -293,7 +299,14 @@ interface SetBillingEmailOverrideParams {
293
299
  */
294
300
  billingEmailOverride: string | null;
295
301
  }
296
- type CustomerList = PaginatedList<CustomerRecord>;
302
+ interface CustomerList {
303
+ data: CustomerRecord[];
304
+ /** Items on this page. */
305
+ count: number;
306
+ /** Total matches across all pages. */
307
+ totalCount: number;
308
+ totalPages: number;
309
+ }
297
310
  interface CreateCustomerParams {
298
311
  name: string;
299
312
  email: string;
@@ -757,9 +770,14 @@ interface WebhookEventEndpoint {
757
770
  events: string[];
758
771
  [key: string]: unknown;
759
772
  }
773
+ /**
774
+ * Public API v1 webhook-event representation. Keyed on `uuid` — there is no
775
+ * numeric id in this shape. `webhookEndpoint.id` stays numeric: endpoint
776
+ * *configuration* (create/update/delete) is still dashboard-only and did
777
+ * not move to `/api/v1`.
778
+ */
760
779
  interface WebhookEvent {
761
- id: number;
762
- endpointId: number;
780
+ uuid: string;
763
781
  /** Eager-loaded endpoint snapshot. */
764
782
  webhookEndpoint: WebhookEventEndpoint;
765
783
  /** Garu event type, e.g. `transaction.payment.paid`. */
@@ -778,17 +796,24 @@ interface WebhookEvent {
778
796
  /** Response body from the most recent attempt, truncated by the gateway. */
779
797
  responseBody: string | null;
780
798
  /**
781
- * When this row is a clone produced by `webhookEvents.resend(id)`, this is
782
- * the numeric id of the original event the clone was forked from. `null`
783
- * on every originally-fired event (and on events resurrected via the
784
- * legacy `webhookEvents.retry(id)` mutation, which mutates in place
785
- * instead of cloning).
799
+ * When this row is a clone produced by `webhookEvents.resend(uuid)`, this
800
+ * is the uuid of the original event the clone was forked from. `null` on
801
+ * every originally-fired event (and on events resurrected via the legacy
802
+ * `webhookEvents.retry(uuid)` mutation, which mutates in place instead of
803
+ * cloning).
786
804
  */
787
- manualResendOf: number | null;
805
+ manualResendOf: string | null;
788
806
  createdAt: string;
789
807
  [key: string]: unknown;
790
808
  }
791
- type WebhookEventList = PaginatedList<WebhookEvent>;
809
+ interface WebhookEventList {
810
+ data: WebhookEvent[];
811
+ /** Items on this page. */
812
+ count: number;
813
+ /** Total matches across all pages. */
814
+ totalCount: number;
815
+ totalPages: number;
816
+ }
792
817
  interface ListWebhookEventsParams {
793
818
  page?: number;
794
819
  limit?: number;
@@ -1315,9 +1340,11 @@ declare class RefundRequests {
1315
1340
  /**
1316
1341
  * Customers — manage your customer base.
1317
1342
  *
1318
- * Customers are scoped to the seller identified by the API key. The backend
1319
- * uses a junction table (`customer_seller_profile`) so the same person can
1320
- * exist across multiple sellers without duplication.
1343
+ * Backed by `/api/v1/customers`, keyed on `uuid`. Customers are scoped to the
1344
+ * seller identified by the API key. The backend uses a junction table
1345
+ * (`customer_seller_profile`) so the same person can exist across multiple
1346
+ * sellers without duplication — creating a customer whose `document` already
1347
+ * exists globally attaches your own profile to it instead of erroring.
1321
1348
  */
1322
1349
  declare class Customers {
1323
1350
  private readonly http;
@@ -1333,29 +1360,35 @@ declare class Customers {
1333
1360
  * phone: '11987654321',
1334
1361
  * personType: 'fisica'
1335
1362
  * });
1363
+ * customer.uuid;
1336
1364
  */
1337
1365
  create(params: CreateCustomerParams): Promise<CustomerRecord>;
1338
1366
  /**
1339
1367
  * List customers for the authenticated seller, with pagination and search.
1340
1368
  *
1341
1369
  * @example
1342
- * const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
1370
+ * const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
1371
+ *
1372
+ * @example
1373
+ * // Customers with at least one overdue scheduled charge (carnê included).
1374
+ * const atRisk = await garu.customers.list({ status: 'overdue' });
1343
1375
  */
1344
1376
  list(params?: ListCustomersParams): Promise<CustomerList>;
1345
1377
  /**
1346
- * Fetch a single customer by numeric ID.
1378
+ * Fetch a single customer by uuid.
1347
1379
  *
1348
1380
  * @example
1349
- * const customer = await garu.customers.get(42);
1381
+ * const customer = await garu.customers.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1350
1382
  */
1351
- get(id: number): Promise<CustomerRecord>;
1383
+ get(uuid: string): Promise<CustomerRecord>;
1352
1384
  /**
1353
- * Update a customer's profile for the current seller.
1385
+ * Update a customer's profile for the current seller. Partial — only the
1386
+ * fields you pass change.
1354
1387
  *
1355
1388
  * @example
1356
- * const updated = await garu.customers.update(42, { name: 'Maria Santos' });
1389
+ * const updated = await garu.customers.update('a1b2c3d4-...', { name: 'Maria Santos' });
1357
1390
  */
1358
- update(id: number, params: UpdateCustomerParams): Promise<CustomerRecord>;
1391
+ update(uuid: string, params: UpdateCustomerParams): Promise<CustomerRecord>;
1359
1392
  /**
1360
1393
  * Set or clear the per-seller billing email override.
1361
1394
  *
@@ -1365,21 +1398,24 @@ declare class Customers {
1365
1398
  *
1366
1399
  * @example
1367
1400
  * // Set
1368
- * await garu.customers.setBillingEmailOverride(42, {
1401
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', {
1369
1402
  * billingEmailOverride: 'cobrancas@empresa.com.br'
1370
1403
  * });
1371
1404
  *
1372
1405
  * // Clear and fall back to the last-used email
1373
- * await garu.customers.setBillingEmailOverride(42, { billingEmailOverride: null });
1406
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', { billingEmailOverride: null });
1374
1407
  */
1375
- setBillingEmailOverride(id: number, params: SetBillingEmailOverrideParams): Promise<CustomerRecord>;
1408
+ setBillingEmailOverride(uuid: string, params: SetBillingEmailOverrideParams): Promise<CustomerRecord>;
1376
1409
  /**
1377
- * Remove a customer from the current seller.
1410
+ * Remove a customer from the current seller (unlinks your profile — the
1411
+ * global customer and other sellers' profiles are untouched).
1378
1412
  *
1379
1413
  * @example
1380
- * await garu.customers.delete(42);
1414
+ * await garu.customers.delete('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1381
1415
  */
1382
- delete(id: number): Promise<void>;
1416
+ delete(uuid: string): Promise<{
1417
+ removed: boolean;
1418
+ }>;
1383
1419
  }
1384
1420
 
1385
1421
  /**
@@ -1730,7 +1766,8 @@ declare class ScheduledCharges {
1730
1766
  /**
1731
1767
  * Webhook events — the seller-facing delivery log for outbound webhooks.
1732
1768
  *
1733
- * Every time the gateway fires a webhook (e.g. `transaction.payment.paid`,
1769
+ * Backed by `/api/v1/webhook-events`, keyed on `uuid`. Every time the
1770
+ * gateway fires a webhook (e.g. `transaction.payment.paid`,
1734
1771
  * `scheduled_charge.cycle_failed`), it persists one row per destination
1735
1772
  * endpoint with the full payload, the HTTP outcome, and the retry schedule.
1736
1773
  * Use this resource to audit deliveries from the seller's API key — the
@@ -1738,6 +1775,7 @@ declare class ScheduledCharges {
1738
1775
  *
1739
1776
  * Webhook endpoint *configuration* (URL, subscribed events, secret) is still
1740
1777
  * dashboard-only — this resource only covers the event log + manual retries.
1778
+ * `webhookEndpoint.id` on every event stays a numeric id for that reason.
1741
1779
  */
1742
1780
  declare class WebhookEvents {
1743
1781
  private readonly http;
@@ -1760,16 +1798,14 @@ declare class WebhookEvents {
1760
1798
  */
1761
1799
  list(params?: ListWebhookEventsParams): Promise<WebhookEventList>;
1762
1800
  /**
1763
- * Fetch one webhook event by numeric ID — includes the full payload, the
1801
+ * Fetch one webhook event by uuid — includes the full payload, the
1764
1802
  * embedded endpoint snapshot, and the most recent response status/body.
1765
1803
  *
1766
1804
  * @example
1767
- * const event = await garu.webhookEvents.get(42);
1768
- * if (event.status === 'failed') {
1769
- * console.log(event.responseStatus, event.responseBody);
1770
- * }
1805
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1806
+ * event.status === 'failed' && event.responseStatus;
1771
1807
  */
1772
- get(id: number): Promise<WebhookEvent>;
1808
+ get(uuid: string): Promise<WebhookEvent>;
1773
1809
  /**
1774
1810
  * @deprecated For most cases prefer {@link resend}, which preserves the
1775
1811
  * original event's audit trail by cloning rather than mutating. `retry()`
@@ -1778,21 +1814,21 @@ declare class WebhookEvents {
1778
1814
  * explicitly want the legacy in-place semantics (and for backwards
1779
1815
  * compatibility with older CLI / MCP releases).
1780
1816
  *
1781
- * Re-deliver a webhook event by ID. Resets it to `pending`, clears the
1817
+ * Re-deliver a webhook event by uuid. Resets it to `pending`, clears the
1782
1818
  * retry schedule, and triggers an immediate delivery attempt. Works on
1783
1819
  * any status (`success`, `failed`, `pending`).
1784
1820
  *
1785
1821
  * @example
1786
1822
  * const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
1787
1823
  * for (const event of failed.data) {
1788
- * await garu.webhookEvents.retry(event.id);
1824
+ * await garu.webhookEvents.retry(event.uuid);
1789
1825
  * }
1790
1826
  */
1791
- retry(id: number): Promise<WebhookEvent>;
1827
+ retry(uuid: string): Promise<WebhookEvent>;
1792
1828
  /**
1793
- * Re-deliver a webhook event by ID, audit-trail preserving. Unlike
1829
+ * Re-deliver a webhook event by uuid, audit-trail preserving. Unlike
1794
1830
  * {@link retry}, this does *not* mutate the original row — it inserts a
1795
- * fresh event (new numeric id) that points back at the source via
1831
+ * fresh event (new uuid) that points back at the source via
1796
1832
  * `manualResendOf`, then dispatches that clone. The original row is
1797
1833
  * untouched, so the historical record of the prior failure (and its
1798
1834
  * response status / body) is preserved.
@@ -1803,27 +1839,27 @@ declare class WebhookEvents {
1803
1839
  * delivery's outcome to remain on the record.
1804
1840
  *
1805
1841
  * **Outbound delivery semantics**: the gateway POSTs the clone with
1806
- * `Idempotency-Key: resend_<originalId>` (where `<originalId>` is the id
1807
- * of the source event, not the clone). Recipient handlers that key off
1842
+ * `Idempotency-Key: resend_<cloneUuid>`. Recipient handlers that key off
1808
1843
  * `Idempotency-Key` will see this as a distinct delivery from the
1809
1844
  * original — distinguishable both by the `resend_` prefix and by reading
1810
1845
  * the response payload's `manualResendOf` field.
1811
1846
  *
1812
- * **SDK→gateway dedup**: the SDK auto-attaches `X-Idempotency-Key`
1813
- * (UUIDv4 unless you pass `idempotencyKey`) so transient transport
1814
- * retries (5xx SDK backoff) cannot create duplicate clones the
1815
- * backend returns the original clone on the second call within 24h.
1847
+ * The SDK also attaches an `X-Idempotency-Key` header (UUIDv4 unless you
1848
+ * pass `idempotencyKey`); the gateway does not currently deduplicate
1849
+ * `/resend` calls against it, so retrying this call from your own code
1850
+ * after a network failure can create more than one clone — pair it with
1851
+ * your own retry-suppression if that matters for your integration.
1816
1852
  *
1817
- * Returns the *clone* event (new id), not the original. The original is
1853
+ * Returns the *clone* event (new uuid), not the original. The original is
1818
1854
  * unchanged on the server.
1819
1855
  *
1820
1856
  * @example
1821
- * const event = await garu.webhookEvents.get(42);
1822
- * const clone = await garu.webhookEvents.resend(42);
1823
- * clone.id !== event.id; // true — clone has its own id
1824
- * clone.manualResendOf === event.id; // true — points back at the source
1857
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1858
+ * const clone = await garu.webhookEvents.resend(event.uuid);
1859
+ * clone.uuid !== event.uuid; // true — clone has its own uuid
1860
+ * clone.manualResendOf === event.uuid; // true — points back at the source
1825
1861
  */
1826
- resend(id: number, params?: ResendWebhookEventParams): Promise<WebhookEvent>;
1862
+ resend(uuid: string, params?: ResendWebhookEventParams): Promise<WebhookEvent>;
1827
1863
  }
1828
1864
 
1829
1865
  interface GaruOptions {
@@ -1929,4 +1965,4 @@ declare class GaruServerError extends GaruAPIError {
1929
1965
  constructor(message: string, status: number, requestId: string | null, body: unknown);
1930
1966
  }
1931
1967
 
1932
- export { type CancelAtPeriodEndScheduledChargeParams, type CancelChargeResult, type CancelInstallmentPlanParams, type CancelRecurrenceScheduledChargeParams, type CardInput, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargePaymentMethod, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateInstallmentPlanParams, type CreateProductParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type Installment, type InstallmentPlan, type InstallmentPlanList, type InstallmentPlanStatus, type InstallmentStatus, type ListChargesParams, type ListCustomersParams, type ListInstallmentPlansParams, type ListProductsParams, type ListRefundRequestsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeInstallmentParams, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type RefundRequest, type RefundRequestList, type RefundRequestStatus, type ReissueInstallmentResult, type RequestPlanRefundParams, type ResendWebhookEventParams, type ResolveRefundRequestParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type UpdateProductParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, webhooks };
1968
+ export { type CancelAtPeriodEndScheduledChargeParams, type CancelChargeResult, type CancelInstallmentPlanParams, type CancelRecurrenceScheduledChargeParams, type CardInput, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargePaymentMethod, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateInstallmentPlanParams, type CreateProductParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type Installment, type InstallmentPlan, type InstallmentPlanList, type InstallmentPlanStatus, type InstallmentStatus, type ListChargesParams, type ListCustomersParams, type ListInstallmentPlansParams, type ListProductsParams, type ListRefundRequestsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeInstallmentParams, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type RefundRequest, type RefundRequestList, type RefundRequestStatus, type ReissueInstallmentResult, type RequestPlanRefundParams, type ResendWebhookEventParams, type ResolveRefundRequestParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetBillingEmailOverrideParams, type SetProductPortalConfigParams, type UpdateCustomerParams, type UpdateProductParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, webhooks };
package/dist/index.d.ts CHANGED
@@ -261,8 +261,15 @@ interface ChargeList {
261
261
  interface CancelChargeResult {
262
262
  canceled: boolean;
263
263
  }
264
+ /**
265
+ * Public API v1 customer representation. Keyed on `uuid` — there is no
266
+ * numeric id in this shape. `installmentPlans.create` and
267
+ * `scheduledCharges.create` still link customers by the internal numeric id
268
+ * (unmigrated resources); fetch that id from the dashboard or the internal
269
+ * `/api/customers` endpoint until they move to `/api/v1` too.
270
+ */
264
271
  interface CustomerRecord {
265
- id: number;
272
+ uuid: string;
266
273
  name: string;
267
274
  email: string;
268
275
  document: string;
@@ -281,10 +288,9 @@ interface CustomerRecord {
281
288
  * Resolved billing email used for outbound seller→customer emails:
282
289
  * `billingEmailOverride ?? per-seller email ?? customer.email`.
283
290
  */
284
- billingEmail?: string;
291
+ billingEmail: string;
285
292
  /** True when a sticky `billingEmailOverride` is set for this seller. */
286
- hasBillingEmailOverride?: boolean;
287
- [key: string]: unknown;
293
+ hasBillingEmailOverride: boolean;
288
294
  }
289
295
  interface SetBillingEmailOverrideParams {
290
296
  /**
@@ -293,7 +299,14 @@ interface SetBillingEmailOverrideParams {
293
299
  */
294
300
  billingEmailOverride: string | null;
295
301
  }
296
- type CustomerList = PaginatedList<CustomerRecord>;
302
+ interface CustomerList {
303
+ data: CustomerRecord[];
304
+ /** Items on this page. */
305
+ count: number;
306
+ /** Total matches across all pages. */
307
+ totalCount: number;
308
+ totalPages: number;
309
+ }
297
310
  interface CreateCustomerParams {
298
311
  name: string;
299
312
  email: string;
@@ -757,9 +770,14 @@ interface WebhookEventEndpoint {
757
770
  events: string[];
758
771
  [key: string]: unknown;
759
772
  }
773
+ /**
774
+ * Public API v1 webhook-event representation. Keyed on `uuid` — there is no
775
+ * numeric id in this shape. `webhookEndpoint.id` stays numeric: endpoint
776
+ * *configuration* (create/update/delete) is still dashboard-only and did
777
+ * not move to `/api/v1`.
778
+ */
760
779
  interface WebhookEvent {
761
- id: number;
762
- endpointId: number;
780
+ uuid: string;
763
781
  /** Eager-loaded endpoint snapshot. */
764
782
  webhookEndpoint: WebhookEventEndpoint;
765
783
  /** Garu event type, e.g. `transaction.payment.paid`. */
@@ -778,17 +796,24 @@ interface WebhookEvent {
778
796
  /** Response body from the most recent attempt, truncated by the gateway. */
779
797
  responseBody: string | null;
780
798
  /**
781
- * When this row is a clone produced by `webhookEvents.resend(id)`, this is
782
- * the numeric id of the original event the clone was forked from. `null`
783
- * on every originally-fired event (and on events resurrected via the
784
- * legacy `webhookEvents.retry(id)` mutation, which mutates in place
785
- * instead of cloning).
799
+ * When this row is a clone produced by `webhookEvents.resend(uuid)`, this
800
+ * is the uuid of the original event the clone was forked from. `null` on
801
+ * every originally-fired event (and on events resurrected via the legacy
802
+ * `webhookEvents.retry(uuid)` mutation, which mutates in place instead of
803
+ * cloning).
786
804
  */
787
- manualResendOf: number | null;
805
+ manualResendOf: string | null;
788
806
  createdAt: string;
789
807
  [key: string]: unknown;
790
808
  }
791
- type WebhookEventList = PaginatedList<WebhookEvent>;
809
+ interface WebhookEventList {
810
+ data: WebhookEvent[];
811
+ /** Items on this page. */
812
+ count: number;
813
+ /** Total matches across all pages. */
814
+ totalCount: number;
815
+ totalPages: number;
816
+ }
792
817
  interface ListWebhookEventsParams {
793
818
  page?: number;
794
819
  limit?: number;
@@ -1315,9 +1340,11 @@ declare class RefundRequests {
1315
1340
  /**
1316
1341
  * Customers — manage your customer base.
1317
1342
  *
1318
- * Customers are scoped to the seller identified by the API key. The backend
1319
- * uses a junction table (`customer_seller_profile`) so the same person can
1320
- * exist across multiple sellers without duplication.
1343
+ * Backed by `/api/v1/customers`, keyed on `uuid`. Customers are scoped to the
1344
+ * seller identified by the API key. The backend uses a junction table
1345
+ * (`customer_seller_profile`) so the same person can exist across multiple
1346
+ * sellers without duplication — creating a customer whose `document` already
1347
+ * exists globally attaches your own profile to it instead of erroring.
1321
1348
  */
1322
1349
  declare class Customers {
1323
1350
  private readonly http;
@@ -1333,29 +1360,35 @@ declare class Customers {
1333
1360
  * phone: '11987654321',
1334
1361
  * personType: 'fisica'
1335
1362
  * });
1363
+ * customer.uuid;
1336
1364
  */
1337
1365
  create(params: CreateCustomerParams): Promise<CustomerRecord>;
1338
1366
  /**
1339
1367
  * List customers for the authenticated seller, with pagination and search.
1340
1368
  *
1341
1369
  * @example
1342
- * const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
1370
+ * const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
1371
+ *
1372
+ * @example
1373
+ * // Customers with at least one overdue scheduled charge (carnê included).
1374
+ * const atRisk = await garu.customers.list({ status: 'overdue' });
1343
1375
  */
1344
1376
  list(params?: ListCustomersParams): Promise<CustomerList>;
1345
1377
  /**
1346
- * Fetch a single customer by numeric ID.
1378
+ * Fetch a single customer by uuid.
1347
1379
  *
1348
1380
  * @example
1349
- * const customer = await garu.customers.get(42);
1381
+ * const customer = await garu.customers.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1350
1382
  */
1351
- get(id: number): Promise<CustomerRecord>;
1383
+ get(uuid: string): Promise<CustomerRecord>;
1352
1384
  /**
1353
- * Update a customer's profile for the current seller.
1385
+ * Update a customer's profile for the current seller. Partial — only the
1386
+ * fields you pass change.
1354
1387
  *
1355
1388
  * @example
1356
- * const updated = await garu.customers.update(42, { name: 'Maria Santos' });
1389
+ * const updated = await garu.customers.update('a1b2c3d4-...', { name: 'Maria Santos' });
1357
1390
  */
1358
- update(id: number, params: UpdateCustomerParams): Promise<CustomerRecord>;
1391
+ update(uuid: string, params: UpdateCustomerParams): Promise<CustomerRecord>;
1359
1392
  /**
1360
1393
  * Set or clear the per-seller billing email override.
1361
1394
  *
@@ -1365,21 +1398,24 @@ declare class Customers {
1365
1398
  *
1366
1399
  * @example
1367
1400
  * // Set
1368
- * await garu.customers.setBillingEmailOverride(42, {
1401
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', {
1369
1402
  * billingEmailOverride: 'cobrancas@empresa.com.br'
1370
1403
  * });
1371
1404
  *
1372
1405
  * // Clear and fall back to the last-used email
1373
- * await garu.customers.setBillingEmailOverride(42, { billingEmailOverride: null });
1406
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', { billingEmailOverride: null });
1374
1407
  */
1375
- setBillingEmailOverride(id: number, params: SetBillingEmailOverrideParams): Promise<CustomerRecord>;
1408
+ setBillingEmailOverride(uuid: string, params: SetBillingEmailOverrideParams): Promise<CustomerRecord>;
1376
1409
  /**
1377
- * Remove a customer from the current seller.
1410
+ * Remove a customer from the current seller (unlinks your profile — the
1411
+ * global customer and other sellers' profiles are untouched).
1378
1412
  *
1379
1413
  * @example
1380
- * await garu.customers.delete(42);
1414
+ * await garu.customers.delete('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1381
1415
  */
1382
- delete(id: number): Promise<void>;
1416
+ delete(uuid: string): Promise<{
1417
+ removed: boolean;
1418
+ }>;
1383
1419
  }
1384
1420
 
1385
1421
  /**
@@ -1730,7 +1766,8 @@ declare class ScheduledCharges {
1730
1766
  /**
1731
1767
  * Webhook events — the seller-facing delivery log for outbound webhooks.
1732
1768
  *
1733
- * Every time the gateway fires a webhook (e.g. `transaction.payment.paid`,
1769
+ * Backed by `/api/v1/webhook-events`, keyed on `uuid`. Every time the
1770
+ * gateway fires a webhook (e.g. `transaction.payment.paid`,
1734
1771
  * `scheduled_charge.cycle_failed`), it persists one row per destination
1735
1772
  * endpoint with the full payload, the HTTP outcome, and the retry schedule.
1736
1773
  * Use this resource to audit deliveries from the seller's API key — the
@@ -1738,6 +1775,7 @@ declare class ScheduledCharges {
1738
1775
  *
1739
1776
  * Webhook endpoint *configuration* (URL, subscribed events, secret) is still
1740
1777
  * dashboard-only — this resource only covers the event log + manual retries.
1778
+ * `webhookEndpoint.id` on every event stays a numeric id for that reason.
1741
1779
  */
1742
1780
  declare class WebhookEvents {
1743
1781
  private readonly http;
@@ -1760,16 +1798,14 @@ declare class WebhookEvents {
1760
1798
  */
1761
1799
  list(params?: ListWebhookEventsParams): Promise<WebhookEventList>;
1762
1800
  /**
1763
- * Fetch one webhook event by numeric ID — includes the full payload, the
1801
+ * Fetch one webhook event by uuid — includes the full payload, the
1764
1802
  * embedded endpoint snapshot, and the most recent response status/body.
1765
1803
  *
1766
1804
  * @example
1767
- * const event = await garu.webhookEvents.get(42);
1768
- * if (event.status === 'failed') {
1769
- * console.log(event.responseStatus, event.responseBody);
1770
- * }
1805
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1806
+ * event.status === 'failed' && event.responseStatus;
1771
1807
  */
1772
- get(id: number): Promise<WebhookEvent>;
1808
+ get(uuid: string): Promise<WebhookEvent>;
1773
1809
  /**
1774
1810
  * @deprecated For most cases prefer {@link resend}, which preserves the
1775
1811
  * original event's audit trail by cloning rather than mutating. `retry()`
@@ -1778,21 +1814,21 @@ declare class WebhookEvents {
1778
1814
  * explicitly want the legacy in-place semantics (and for backwards
1779
1815
  * compatibility with older CLI / MCP releases).
1780
1816
  *
1781
- * Re-deliver a webhook event by ID. Resets it to `pending`, clears the
1817
+ * Re-deliver a webhook event by uuid. Resets it to `pending`, clears the
1782
1818
  * retry schedule, and triggers an immediate delivery attempt. Works on
1783
1819
  * any status (`success`, `failed`, `pending`).
1784
1820
  *
1785
1821
  * @example
1786
1822
  * const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
1787
1823
  * for (const event of failed.data) {
1788
- * await garu.webhookEvents.retry(event.id);
1824
+ * await garu.webhookEvents.retry(event.uuid);
1789
1825
  * }
1790
1826
  */
1791
- retry(id: number): Promise<WebhookEvent>;
1827
+ retry(uuid: string): Promise<WebhookEvent>;
1792
1828
  /**
1793
- * Re-deliver a webhook event by ID, audit-trail preserving. Unlike
1829
+ * Re-deliver a webhook event by uuid, audit-trail preserving. Unlike
1794
1830
  * {@link retry}, this does *not* mutate the original row — it inserts a
1795
- * fresh event (new numeric id) that points back at the source via
1831
+ * fresh event (new uuid) that points back at the source via
1796
1832
  * `manualResendOf`, then dispatches that clone. The original row is
1797
1833
  * untouched, so the historical record of the prior failure (and its
1798
1834
  * response status / body) is preserved.
@@ -1803,27 +1839,27 @@ declare class WebhookEvents {
1803
1839
  * delivery's outcome to remain on the record.
1804
1840
  *
1805
1841
  * **Outbound delivery semantics**: the gateway POSTs the clone with
1806
- * `Idempotency-Key: resend_<originalId>` (where `<originalId>` is the id
1807
- * of the source event, not the clone). Recipient handlers that key off
1842
+ * `Idempotency-Key: resend_<cloneUuid>`. Recipient handlers that key off
1808
1843
  * `Idempotency-Key` will see this as a distinct delivery from the
1809
1844
  * original — distinguishable both by the `resend_` prefix and by reading
1810
1845
  * the response payload's `manualResendOf` field.
1811
1846
  *
1812
- * **SDK→gateway dedup**: the SDK auto-attaches `X-Idempotency-Key`
1813
- * (UUIDv4 unless you pass `idempotencyKey`) so transient transport
1814
- * retries (5xx SDK backoff) cannot create duplicate clones the
1815
- * backend returns the original clone on the second call within 24h.
1847
+ * The SDK also attaches an `X-Idempotency-Key` header (UUIDv4 unless you
1848
+ * pass `idempotencyKey`); the gateway does not currently deduplicate
1849
+ * `/resend` calls against it, so retrying this call from your own code
1850
+ * after a network failure can create more than one clone — pair it with
1851
+ * your own retry-suppression if that matters for your integration.
1816
1852
  *
1817
- * Returns the *clone* event (new id), not the original. The original is
1853
+ * Returns the *clone* event (new uuid), not the original. The original is
1818
1854
  * unchanged on the server.
1819
1855
  *
1820
1856
  * @example
1821
- * const event = await garu.webhookEvents.get(42);
1822
- * const clone = await garu.webhookEvents.resend(42);
1823
- * clone.id !== event.id; // true — clone has its own id
1824
- * clone.manualResendOf === event.id; // true — points back at the source
1857
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1858
+ * const clone = await garu.webhookEvents.resend(event.uuid);
1859
+ * clone.uuid !== event.uuid; // true — clone has its own uuid
1860
+ * clone.manualResendOf === event.uuid; // true — points back at the source
1825
1861
  */
1826
- resend(id: number, params?: ResendWebhookEventParams): Promise<WebhookEvent>;
1862
+ resend(uuid: string, params?: ResendWebhookEventParams): Promise<WebhookEvent>;
1827
1863
  }
1828
1864
 
1829
1865
  interface GaruOptions {
@@ -1929,4 +1965,4 @@ declare class GaruServerError extends GaruAPIError {
1929
1965
  constructor(message: string, status: number, requestId: string | null, body: unknown);
1930
1966
  }
1931
1967
 
1932
- export { type CancelAtPeriodEndScheduledChargeParams, type CancelChargeResult, type CancelInstallmentPlanParams, type CancelRecurrenceScheduledChargeParams, type CardInput, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargePaymentMethod, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateInstallmentPlanParams, type CreateProductParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type Installment, type InstallmentPlan, type InstallmentPlanList, type InstallmentPlanStatus, type InstallmentStatus, type ListChargesParams, type ListCustomersParams, type ListInstallmentPlansParams, type ListProductsParams, type ListRefundRequestsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeInstallmentParams, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type RefundRequest, type RefundRequestList, type RefundRequestStatus, type ReissueInstallmentResult, type RequestPlanRefundParams, type ResendWebhookEventParams, type ResolveRefundRequestParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetProductPortalConfigParams, type UpdateCustomerParams, type UpdateProductParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, webhooks };
1968
+ export { type CancelAtPeriodEndScheduledChargeParams, type CancelChargeResult, type CancelInstallmentPlanParams, type CancelRecurrenceScheduledChargeParams, type CardInput, type ChangePaymentMethodScheduledChargeParams, type Charge, type ChargeList, type ChargeNowOutcome, type ChargeNowReason, type ChargeNowResult, type ChargePaymentMethod, type ChargeStatus, type CreateChargeParams, type CreateCustomerParams, type CreateInstallmentPlanParams, type CreateProductParams, type CreateScheduledChargeParams, type Customer, type CustomerList, type CustomerRecord, type FailurePayload, Garu, GaruAPIError, GaruAuthenticationError, GaruConnectionError, GaruError, type GaruErrorCode, type GaruFailureCode, GaruNotFoundError, type GaruOptions, GaruPermissionError, GaruRateLimitError, GaruServerError, GaruSignatureVerificationError, GaruValidationError, type Installment, type InstallmentPlan, type InstallmentPlanList, type InstallmentPlanStatus, type InstallmentStatus, type ListChargesParams, type ListCustomersParams, type ListInstallmentPlansParams, type ListProductsParams, type ListRefundRequestsParams, type ListScheduledChargeAttemptsParams, type ListScheduledChargesParams, type ListWebhookEventsParams, type MarkPaidScheduledChargeParams, type MetaFeatures, type MetaResponse, type PaginatedList, type PauseScheduledChargeParams, type PaymentMethodExpiredPayload, type PaymentMethodExpiringPayload, type PostponeInstallmentParams, type PostponeScheduledChargeParams, type Product, type ProductList, type ProductPortalConfig, type RecurrenceConfig, type RecurrenceInterval, type RefundChargeParams, type RefundRequest, type RefundRequestList, type RefundRequestStatus, type ReissueInstallmentResult, type RequestPlanRefundParams, type ResendWebhookEventParams, type ResolveRefundRequestParams, type ScheduledChargeActor, type ScheduledChargeAttempt, type ScheduledChargeAttemptList, type ScheduledChargeAttemptSource, type ScheduledChargeAttemptStatus, type ScheduledChargeDetail, type ScheduledChargeEvent, type ScheduledChargeEventType, type ScheduledChargeLinkedTransaction, type ScheduledChargeList, type ScheduledChargeRecord, type ScheduledChargeStatus, type ScheduledChargeType, type ScheduledPaymentMethod, type SetBillingEmailOverrideParams, type SetProductPortalConfigParams, type UpdateCustomerParams, type UpdateProductParams, type VerifiedWebhook, type VerifyWebhookParams, type WebhookEvent, type WebhookEventEndpoint, type WebhookEventList, type WebhookEventStatus, webhooks };
package/dist/index.js CHANGED
@@ -627,10 +627,11 @@ var Customers = class {
627
627
  * phone: '11987654321',
628
628
  * personType: 'fisica'
629
629
  * });
630
+ * customer.uuid;
630
631
  */
631
632
  async create(params) {
632
633
  return this.http.call(
633
- (signal) => this.http.client.POST("/api/customers", {
634
+ (signal) => this.http.client.POST("/api/v1/customers", {
634
635
  body: params,
635
636
  signal
636
637
  }).then((r) => r)
@@ -640,7 +641,11 @@ var Customers = class {
640
641
  * List customers for the authenticated seller, with pagination and search.
641
642
  *
642
643
  * @example
643
- * const { data, meta } = await garu.customers.list({ search: 'maria', limit: 10 });
644
+ * const { data, totalCount } = await garu.customers.list({ search: 'maria', limit: 10 });
645
+ *
646
+ * @example
647
+ * // Customers with at least one overdue scheduled charge (carnê included).
648
+ * const atRisk = await garu.customers.list({ status: 'overdue' });
644
649
  */
645
650
  async list(params = {}) {
646
651
  const query = {};
@@ -649,7 +654,7 @@ var Customers = class {
649
654
  if (params.search) query.search = params.search;
650
655
  if (params.status) query.status = params.status;
651
656
  const qs = new URLSearchParams(query).toString();
652
- const url = `/api/customers${qs ? `?${qs}` : ""}`;
657
+ const url = `/api/v1/customers${qs ? `?${qs}` : ""}`;
653
658
  return this.http.call(
654
659
  (signal) => this.http.client.GET(url, { signal }).then(
655
660
  (r) => r
@@ -657,27 +662,28 @@ var Customers = class {
657
662
  );
658
663
  }
659
664
  /**
660
- * Fetch a single customer by numeric ID.
665
+ * Fetch a single customer by uuid.
661
666
  *
662
667
  * @example
663
- * const customer = await garu.customers.get(42);
668
+ * const customer = await garu.customers.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
664
669
  */
665
- async get(id) {
670
+ async get(uuid) {
666
671
  return this.http.call(
667
- (signal) => this.http.client.GET(`/api/customers/${id}`, { signal }).then(
672
+ (signal) => this.http.client.GET(`/api/v1/customers/${uuid}`, { signal }).then(
668
673
  (r) => r
669
674
  )
670
675
  );
671
676
  }
672
677
  /**
673
- * Update a customer's profile for the current seller.
678
+ * Update a customer's profile for the current seller. Partial — only the
679
+ * fields you pass change.
674
680
  *
675
681
  * @example
676
- * const updated = await garu.customers.update(42, { name: 'Maria Santos' });
682
+ * const updated = await garu.customers.update('a1b2c3d4-...', { name: 'Maria Santos' });
677
683
  */
678
- async update(id, params) {
684
+ async update(uuid, params) {
679
685
  return this.http.call(
680
- (signal) => this.http.client.PUT(`/api/customers/${id}`, {
686
+ (signal) => this.http.client.PATCH(`/api/v1/customers/${uuid}`, {
681
687
  body: params,
682
688
  signal
683
689
  }).then((r) => r)
@@ -692,30 +698,31 @@ var Customers = class {
692
698
  *
693
699
  * @example
694
700
  * // Set
695
- * await garu.customers.setBillingEmailOverride(42, {
701
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', {
696
702
  * billingEmailOverride: 'cobrancas@empresa.com.br'
697
703
  * });
698
704
  *
699
705
  * // Clear and fall back to the last-used email
700
- * await garu.customers.setBillingEmailOverride(42, { billingEmailOverride: null });
706
+ * await garu.customers.setBillingEmailOverride('a1b2c3d4-...', { billingEmailOverride: null });
701
707
  */
702
- async setBillingEmailOverride(id, params) {
708
+ async setBillingEmailOverride(uuid, params) {
703
709
  return this.http.call(
704
- (signal) => this.http.client.PATCH(`/api/customers/${id}/billing-email-override`, {
710
+ (signal) => this.http.client.PATCH(`/api/v1/customers/${uuid}/billing-email-override`, {
705
711
  body: params,
706
712
  signal
707
713
  }).then((r) => r)
708
714
  );
709
715
  }
710
716
  /**
711
- * Remove a customer from the current seller.
717
+ * Remove a customer from the current seller (unlinks your profile — the
718
+ * global customer and other sellers' profiles are untouched).
712
719
  *
713
720
  * @example
714
- * await garu.customers.delete(42);
721
+ * await garu.customers.delete('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
715
722
  */
716
- async delete(id) {
717
- await this.http.call(
718
- (signal) => this.http.client.DELETE(`/api/customers/${id}`, {
723
+ async delete(uuid) {
724
+ return this.http.call(
725
+ (signal) => this.http.client.DELETE(`/api/v1/customers/${uuid}`, {
719
726
  body: {},
720
727
  signal
721
728
  }).then((r) => r)
@@ -1280,42 +1287,31 @@ var WebhookEvents = class {
1280
1287
  * });
1281
1288
  */
1282
1289
  async list(params = {}) {
1283
- const qs = new URLSearchParams();
1284
- if (params.page !== void 0) qs.set("page", String(params.page));
1285
- if (params.limit !== void 0) qs.set("limit", String(params.limit));
1286
- if (params.status) qs.set("status", params.status);
1287
- if (params.eventType) qs.set("event_type", params.eventType);
1288
- if (params.endpointId !== void 0) qs.set("endpoint_id", String(params.endpointId));
1289
- const query = qs.toString();
1290
- const url = `/api/webhook-events${query ? `?${query}` : ""}`;
1291
- const raw = await this.http.call(
1290
+ const query = {};
1291
+ if (params.page !== void 0) query.page = String(params.page);
1292
+ if (params.limit !== void 0) query.limit = String(params.limit);
1293
+ if (params.status) query.status = params.status;
1294
+ if (params.eventType) query.eventType = params.eventType;
1295
+ if (params.endpointId !== void 0) query.endpointId = String(params.endpointId);
1296
+ const qs = new URLSearchParams(query).toString();
1297
+ const url = `/api/v1/webhook-events${qs ? `?${qs}` : ""}`;
1298
+ return this.http.call(
1292
1299
  (signal) => this.http.client.GET(url, { signal }).then(
1293
1300
  (r) => r
1294
1301
  )
1295
1302
  );
1296
- return {
1297
- data: raw.events,
1298
- meta: {
1299
- page: raw.page,
1300
- limit: raw.limit,
1301
- total: raw.total,
1302
- totalPages: raw.pages
1303
- }
1304
- };
1305
1303
  }
1306
1304
  /**
1307
- * Fetch one webhook event by numeric ID — includes the full payload, the
1305
+ * Fetch one webhook event by uuid — includes the full payload, the
1308
1306
  * embedded endpoint snapshot, and the most recent response status/body.
1309
1307
  *
1310
1308
  * @example
1311
- * const event = await garu.webhookEvents.get(42);
1312
- * if (event.status === 'failed') {
1313
- * console.log(event.responseStatus, event.responseBody);
1314
- * }
1309
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1310
+ * event.status === 'failed' && event.responseStatus;
1315
1311
  */
1316
- async get(id) {
1312
+ async get(uuid) {
1317
1313
  return this.http.call(
1318
- (signal) => this.http.client.GET(`/api/webhook-events/${id}`, { signal }).then(
1314
+ (signal) => this.http.client.GET(`/api/v1/webhook-events/${uuid}`, { signal }).then(
1319
1315
  (r) => r
1320
1316
  )
1321
1317
  );
@@ -1328,28 +1324,28 @@ var WebhookEvents = class {
1328
1324
  * explicitly want the legacy in-place semantics (and for backwards
1329
1325
  * compatibility with older CLI / MCP releases).
1330
1326
  *
1331
- * Re-deliver a webhook event by ID. Resets it to `pending`, clears the
1327
+ * Re-deliver a webhook event by uuid. Resets it to `pending`, clears the
1332
1328
  * retry schedule, and triggers an immediate delivery attempt. Works on
1333
1329
  * any status (`success`, `failed`, `pending`).
1334
1330
  *
1335
1331
  * @example
1336
1332
  * const failed = await garu.webhookEvents.list({ status: 'failed', limit: 5 });
1337
1333
  * for (const event of failed.data) {
1338
- * await garu.webhookEvents.retry(event.id);
1334
+ * await garu.webhookEvents.retry(event.uuid);
1339
1335
  * }
1340
1336
  */
1341
- async retry(id) {
1337
+ async retry(uuid) {
1342
1338
  return this.http.call(
1343
- (signal) => this.http.client.POST(`/api/webhook-events/${id}/retry`, {
1339
+ (signal) => this.http.client.POST(`/api/v1/webhook-events/${uuid}/retry`, {
1344
1340
  body: {},
1345
1341
  signal
1346
1342
  }).then((r) => r)
1347
1343
  );
1348
1344
  }
1349
1345
  /**
1350
- * Re-deliver a webhook event by ID, audit-trail preserving. Unlike
1346
+ * Re-deliver a webhook event by uuid, audit-trail preserving. Unlike
1351
1347
  * {@link retry}, this does *not* mutate the original row — it inserts a
1352
- * fresh event (new numeric id) that points back at the source via
1348
+ * fresh event (new uuid) that points back at the source via
1353
1349
  * `manualResendOf`, then dispatches that clone. The original row is
1354
1350
  * untouched, so the historical record of the prior failure (and its
1355
1351
  * response status / body) is preserved.
@@ -1360,30 +1356,30 @@ var WebhookEvents = class {
1360
1356
  * delivery's outcome to remain on the record.
1361
1357
  *
1362
1358
  * **Outbound delivery semantics**: the gateway POSTs the clone with
1363
- * `Idempotency-Key: resend_<originalId>` (where `<originalId>` is the id
1364
- * of the source event, not the clone). Recipient handlers that key off
1359
+ * `Idempotency-Key: resend_<cloneUuid>`. Recipient handlers that key off
1365
1360
  * `Idempotency-Key` will see this as a distinct delivery from the
1366
1361
  * original — distinguishable both by the `resend_` prefix and by reading
1367
1362
  * the response payload's `manualResendOf` field.
1368
1363
  *
1369
- * **SDK→gateway dedup**: the SDK auto-attaches `X-Idempotency-Key`
1370
- * (UUIDv4 unless you pass `idempotencyKey`) so transient transport
1371
- * retries (5xx SDK backoff) cannot create duplicate clones the
1372
- * backend returns the original clone on the second call within 24h.
1364
+ * The SDK also attaches an `X-Idempotency-Key` header (UUIDv4 unless you
1365
+ * pass `idempotencyKey`); the gateway does not currently deduplicate
1366
+ * `/resend` calls against it, so retrying this call from your own code
1367
+ * after a network failure can create more than one clone — pair it with
1368
+ * your own retry-suppression if that matters for your integration.
1373
1369
  *
1374
- * Returns the *clone* event (new id), not the original. The original is
1370
+ * Returns the *clone* event (new uuid), not the original. The original is
1375
1371
  * unchanged on the server.
1376
1372
  *
1377
1373
  * @example
1378
- * const event = await garu.webhookEvents.get(42);
1379
- * const clone = await garu.webhookEvents.resend(42);
1380
- * clone.id !== event.id; // true — clone has its own id
1381
- * clone.manualResendOf === event.id; // true — points back at the source
1374
+ * const event = await garu.webhookEvents.get('a1b2c3d4-e5f6-7890-abcd-ef1234567890');
1375
+ * const clone = await garu.webhookEvents.resend(event.uuid);
1376
+ * clone.uuid !== event.uuid; // true — clone has its own uuid
1377
+ * clone.manualResendOf === event.uuid; // true — points back at the source
1382
1378
  */
1383
- async resend(id, params = {}) {
1379
+ async resend(uuid, params = {}) {
1384
1380
  const idempotencyKey = params.idempotencyKey ?? generateIdempotencyKey();
1385
1381
  return this.http.call(
1386
- (signal) => this.http.client.POST(`/api/webhook-events/${id}/resend`, {
1382
+ (signal) => this.http.client.POST(`/api/v1/webhook-events/${uuid}/resend`, {
1387
1383
  body: {},
1388
1384
  headers: { "X-Idempotency-Key": idempotencyKey },
1389
1385
  signal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@garuhq/node",
3
- "version": "1.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Official Node.js / TypeScript SDK for the Garu payment gateway.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://garu.com.br",