@iteradian-rpc/sdk 1.1.1 → 1.2.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 CHANGED
@@ -6,7 +6,7 @@
6
6
  <p align="center">
7
7
  <img src="https://img.shields.io/badge/language-TypeScript-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" />
8
8
  <img src="https://img.shields.io/badge/node-%3E%3D16.0.0-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node 16+" />
9
- <img src="https://img.shields.io/badge/version-1.0.0-green?style=flat-square" alt="Version" />
9
+ <img src="https://img.shields.io/badge/version-1.2.0-green?style=flat-square" alt="Version" />
10
10
  <img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License" />
11
11
  <img src="https://img.shields.io/badge/npm-%40iteradian%2Fsdk-CB3837?style=flat-square&logo=npm&logoColor=white" alt="npm" />
12
12
  <img src="https://img.shields.io/badge/deps-zero-brightgreen?style=flat-square" alt="Zero Dependencies" />
@@ -57,11 +57,15 @@ const client = new IteradianClient({
57
57
  });
58
58
 
59
59
  // Login — sets the access token automatically
60
- const tokens = await client.auth.login({
60
+ const login = await client.auth.login({
61
61
  email: "user@example.com",
62
62
  password: "password123",
63
63
  });
64
- console.log(`Logged in as ${tokens.user.email}`);
64
+ if (login.requires2FA) {
65
+ // Two-factor auth is on: log in again with a code (see Authentication).
66
+ throw new Error("2FA code required");
67
+ }
68
+ console.log(`Logged in as ${login.user?.email}`);
65
69
 
66
70
  // List organizations
67
71
  const orgs = await client.organizations.list();
@@ -81,12 +85,13 @@ if (orgs.length > 0) {
81
85
  name: "Production Key",
82
86
  environment: "live",
83
87
  });
84
- console.log(`Created key: ${key.prefix}`);
88
+ // The full key is shown once, in `secret`.
89
+ console.log(`Created key: ${key.prefix} (${key.secret})`);
85
90
 
86
91
  // Query logs
87
92
  const logs = await client.logs.query(orgId, {
88
93
  status: "error",
89
- pageSize: 50,
94
+ limit: 50,
90
95
  });
91
96
  console.log(`Total logs: ${logs.total}`);
92
97
  }
@@ -163,8 +168,16 @@ client.clearAccessToken();
163
168
  ### Authentication (`client.auth`)
164
169
 
165
170
  ```typescript
166
- // Login (token set automatically)
167
- const tokens = await client.auth.login({ email: "...", password: "..." });
171
+ // Login (the access token is set automatically when the answer has one)
172
+ const login = await client.auth.login({ email: "...", password: "..." });
173
+
174
+ // With two-factor auth on, a login without a code answers
175
+ // { requires2FA: true } and no tokens. Log in again with a code:
176
+ if (login.requires2FA) {
177
+ await client.auth.login({ email: "...", password: "...", twoFactorCode: "123456" });
178
+ // or, with a one-time backup code:
179
+ // await client.auth.login({ email: "...", password: "...", backupCode: "..." });
180
+ }
168
181
 
169
182
  // Register — does NOT sign in. Answers { message, email } and emails a
170
183
  // confirmation link; log in once the address is confirmed.
@@ -183,19 +196,25 @@ const tokens = await client.auth.refresh(refreshToken);
183
196
  // Logout
184
197
  await client.auth.logout();
185
198
 
199
+ // Email verification
200
+ await client.auth.verifyEmail(token);
201
+ await client.auth.resendVerification("user@example.com");
202
+
186
203
  // Two-Factor Authentication
187
- const setup = await client.auth.enable2FA({ password: "..." });
204
+ const setup = await client.auth.enable2FA("password");
188
205
  console.log(`Secret: ${setup.secret}`);
189
206
  console.log(`QR Code: ${setup.qrCode}`);
190
- await client.auth.verify2FA({ code: "123456" });
207
+ const { backupCodes } = await client.auth.verify2FA("123456");
208
+ const fresh = await client.auth.regenerateBackupCodes("password");
191
209
  await client.auth.disable2FA("password", "123456"); // password + current 6-digit TOTP code
192
210
 
193
211
  // Magic Link
194
- await client.auth.sendMagicLink({ email: "user@example.com" });
212
+ await client.auth.requestMagicLink("user@example.com");
213
+ await client.auth.loginWithMagicLink(tokenFromEmail);
195
214
 
196
215
  // Password Reset
197
- await client.auth.forgotPassword({ email: "user@example.com" });
198
- await client.auth.resetPassword({ token: "...", newPassword: "..." });
216
+ await client.auth.forgotPassword("user@example.com");
217
+ await client.auth.resetPassword(tokenFromEmail, "new-password");
199
218
  ```
200
219
 
201
220
  ### Organizations (`client.organizations`)
@@ -203,15 +222,23 @@ await client.auth.resetPassword({ token: "...", newPassword: "..." });
203
222
  ```typescript
204
223
  // CRUD
205
224
  const orgs = await client.organizations.list();
206
- const org = await client.organizations.create({
225
+ // `name`, `planId` and `acceptedTerms` are required; `slug` and
226
+ // `billingInterval` ("month" | "year") are optional.
227
+ const created = await client.organizations.create({
207
228
  name: "My Org",
229
+ planId: "plan_free",
230
+ acceptedTerms: true,
208
231
  slug: "my-org",
209
232
  });
210
233
  const org = await client.organizations.get(orgId);
234
+ await client.organizations.update(orgId, { name: "Renamed" });
211
235
  await client.organizations.delete(orgId);
236
+ await client.organizations.leave(orgId);
237
+ const perms = await client.organizations.getMyPermissions(orgId);
212
238
 
213
239
  // Members
214
240
  const members = await client.organizations.listMembers(orgId);
241
+ await client.organizations.updateMemberRole(orgId, memberId, "viewer");
215
242
  await client.organizations.removeMember(orgId, memberId);
216
243
 
217
244
  // Invitations — inviting creates a pending invite; the invitee becomes a
@@ -239,9 +266,12 @@ const key = await client.apiKeys.create(orgId, {
239
266
  name: "Key Name",
240
267
  environment: "live",
241
268
  });
242
- await client.apiKeys.revoke(orgId, keyId);
243
- const newKey = await client.apiKeys.rotate(orgId, keyId);
244
- const analytics = await client.apiKeys.getAnalytics(orgId, keyId);
269
+ // The full key is shown once, in `secret`. `key.key` is a deprecated alias.
270
+ console.log(key.secret);
271
+ await client.apiKeys.update(orgId, key.id, { name: "Renamed" });
272
+ const newKey = await client.apiKeys.rotate(orgId, key.id); // new key in newKey.secret
273
+ const analytics = await client.apiKeys.getAnalytics(orgId, key.id, "7d");
274
+ await client.apiKeys.revoke(orgId, key.id);
245
275
  ```
246
276
 
247
277
  ### Endpoints (`client.endpoints`)
@@ -249,88 +279,124 @@ const analytics = await client.apiKeys.getAnalytics(orgId, keyId);
249
279
  ```typescript
250
280
  // Networks
251
281
  const networks = await client.endpoints.getNetworks();
282
+ const network = await client.endpoints.getNetwork(networkId);
252
283
 
253
284
  // Endpoint management
254
285
  const endpoints = await client.endpoints.list(orgId);
255
286
  const endpoint = await client.endpoints.create(orgId, {
256
- name: "...",
287
+ name: "My endpoint",
257
288
  networkId: "...",
258
- region: "us-east-1",
289
+ region: "eu_central",
259
290
  });
260
- await client.endpoints.delete(orgId, endpointId);
261
- const paused = await client.endpoints.pause(orgId, endpointId);
262
- const resumed = await client.endpoints.resume(orgId, endpointId);
263
- const health = await client.endpoints.checkHealth(orgId, endpointId);
264
- const metrics = await client.endpoints.getMetrics(orgId, endpointId);
291
+ await client.endpoints.update(orgId, endpoint.id, { name: "Renamed" });
292
+ await client.endpoints.delete(orgId, endpoint.id);
293
+ const paused = await client.endpoints.pause(orgId, endpoint.id);
294
+ const resumed = await client.endpoints.resume(orgId, endpoint.id);
295
+ await client.endpoints.updatePriorities(orgId, [{ id: endpoint.id, priority: 2 }]);
296
+
297
+ // Health and metrics
298
+ const check = await client.endpoints.checkHealth(orgId, endpoint.id); // runs a check now
299
+ const health = await client.endpoints.getHealth(orgId, endpoint.id); // current health
300
+ const summary = await client.endpoints.getHealthOverview(orgId);
301
+ const metrics = await client.endpoints.getMetrics(orgId, endpoint.id);
302
+ const ranged = await client.endpoints.getMetrics(
303
+ orgId,
304
+ endpoint.id,
305
+ "2026-01-01T00:00:00Z",
306
+ "2026-01-02T00:00:00Z",
307
+ );
265
308
  ```
266
309
 
310
+ Decimal fields such as `avgLatencyMs`, `successRate` and `uptime` can arrive as
311
+ numeric strings; they are typed `number | string`, so use `Number(value)`.
312
+
267
313
  ### Usage & Dashboard
268
314
 
269
315
  ```typescript
270
- // Usage
271
- const usage = await client.usage.get(orgId, {
272
- from: "2024-01-01",
273
- to: "2024-01-31",
274
- });
275
-
276
- // Dashboard
277
- const data = await client.dashboard.get(orgId, { period: "7d" });
316
+ // Usage: a list of rows (one per key per day)
317
+ const rows = await client.usage.get(orgId, "2026-01-01", "2026-01-31");
318
+ const usage = await client.usage.getSummary(orgId);
319
+
320
+ // Dashboard. The optional second argument is the API timeRange:
321
+ // last_hour, last_24_hours (default), last_7_days, last_30_days or custom.
322
+ // The short forms "1h", "24h", "7d" and "30d" are translated.
323
+ const data = await client.dashboard.get(orgId, "7d");
324
+ const custom = await client.dashboard.get(orgId, "custom", { from: "2026-01-01", to: "2026-01-07" });
278
325
  const health = await client.dashboard.getHealth(orgId);
279
- const stats = await client.dashboard.getQuickStats(orgId, { period: "24h" });
326
+ const stats = await client.dashboard.getQuickStats(orgId, "24h");
327
+ const requestRate = await client.dashboard.getRequestRate(orgId); // { currentRate, timeSeries, ... }
328
+ const errorRate = await client.dashboard.getErrorRate(orgId);
329
+ const latency = await client.dashboard.getLatency(orgId); // { p50, p95, p99, ... }
330
+ const perf = await client.dashboard.getPerformance(orgId);
280
331
  ```
281
332
 
282
333
  ### Alerts (`client.alerts`)
283
334
 
284
335
  ```typescript
285
- // Alerts
336
+ // Alerts. list() returns the alerts array; overview() also has the counters,
337
+ // rules and channels.
286
338
  const alerts = await client.alerts.list(orgId);
339
+ const overview = await client.alerts.overview(orgId);
287
340
  const ack = await client.alerts.acknowledge(orgId, alertId);
288
341
  const resolved = await client.alerts.resolve(orgId, alertId);
342
+ await client.alerts.evaluate(orgId);
289
343
 
290
- // Alert Rules
344
+ // Alert Rules. type is one of high_error_rate, high_latency,
345
+ // rate_limit_exceeded, quota_warning, service_down, key_expiring,
346
+ // unusual_traffic; config holds the thresholds for that type.
291
347
  const rules = await client.alerts.listRules(orgId);
292
348
  const rule = await client.alerts.createRule(orgId, {
293
- name: "High Latency",
294
- metric: "latency_p95",
295
- condition: "greater_than",
296
- threshold: 500,
297
- severity: "warning",
349
+ name: "High error rate",
350
+ type: "high_error_rate",
351
+ config: { threshold: 5 },
352
+ severity: "warning", // info | warning | error | critical
353
+ cooldownSeconds: 900, // at least 60
298
354
  isEnabled: true,
299
- cooldownMinutes: 15,
300
355
  });
301
- await client.alerts.deleteRule(orgId, ruleId);
302
-
303
- // Channels
304
- const channels = await client.alerts.getChannels(orgId);
305
- await client.alerts.testChannel(orgId, channelId);
356
+ await client.alerts.updateRule(orgId, rule.id, { name: "Renamed" });
357
+ await client.alerts.toggleRule(orgId, rule.id);
358
+ await client.alerts.seedDefaults(orgId);
359
+ await client.alerts.deleteRule(orgId, rule.id);
360
+
361
+ // Channels. type is email | webhook | slack.
362
+ const channels = await client.alerts.listChannels(orgId);
363
+ const channel = await client.alerts.createChannel(orgId, {
364
+ name: "Ops webhook",
365
+ type: "webhook",
366
+ config: { url: "https://example.com/hook" },
367
+ });
368
+ await client.alerts.updateChannel(orgId, channel.id, { isEnabled: false });
369
+ await client.alerts.testChannel(orgId, channel.id);
370
+ await client.alerts.deleteChannel(orgId, channel.id);
306
371
  ```
307
372
 
308
373
  ### Logs (`client.logs`)
309
374
 
310
375
  ```typescript
311
- // Query with filters
376
+ // Query with filters. Page with limit (1-200) and offset.
312
377
  const logs = await client.logs.query(orgId, {
313
- page: 1,
314
- pageSize: 50,
378
+ limit: 50,
379
+ offset: 0,
315
380
  status: "error",
316
381
  method: "eth_call",
317
- network: "ethereum",
382
+ network: "eth-mainnet",
383
+ minLatencyMs: 100,
318
384
  sortBy: "timestamp",
319
385
  sortOrder: "desc",
320
386
  });
321
- console.log(`Page ${logs.page}/${logs.totalPages}`);
387
+ console.log(`${logs.logs.length} of ${logs.total}`);
322
388
  for (const log of logs.logs) {
323
389
  console.log(` [${log.status}] ${log.method} (${log.latencyMs}ms)`);
324
390
  }
325
391
 
326
392
  // Get single log
327
- const log = await client.logs.get(orgId, logId);
393
+ const log = await client.logs.get(orgId, logs.logs[0].id);
328
394
 
329
395
  // Filter options
330
396
  const filters = await client.logs.getFilterOptions(orgId);
331
397
 
332
398
  // Stats
333
- const stats = await client.logs.getStats(orgId, { period: "24h" });
399
+ const stats = await client.logs.getStats(orgId);
334
400
  ```
335
401
 
336
402
  ### Subscriptions (`client.subscriptions`)
@@ -339,7 +405,7 @@ const stats = await client.logs.getStats(orgId, { period: "24h" });
339
405
  const sub = await client.subscriptions.get(orgId);
340
406
  // The caller confirms the user accepted the plan-change billing terms; the
341
407
  // server rejects the change (400) unless acceptedTerms is true.
342
- const updated = await client.subscriptions.changePlan(orgId, "pro", {
408
+ const updated = await client.subscriptions.changePlan(orgId, "plan_builder", {
343
409
  acceptedTerms: true,
344
410
  });
345
411
  const cancelled = await client.subscriptions.cancel(orgId);
@@ -357,22 +423,41 @@ const plan = await client.plans.get(planId);
357
423
  ### Support (`client.support`)
358
424
 
359
425
  ```typescript
426
+ // listTickets() returns the tickets array.
360
427
  const tickets = await client.support.listTickets(orgId);
361
428
  const ticket = await client.support.createTicket(orgId, {
362
429
  subject: "API returning 500 errors",
363
- category: "technical",
364
- priority: "high",
365
- message: "Detailed description...",
430
+ body: "Detailed description...",
431
+ category: "technical", // optional
432
+ priority: "high", // optional: low | medium | high | urgent
366
433
  });
367
- const detail = await client.support.getTicket(orgId, ticketId);
368
- await client.support.addMessage(orgId, ticketId, {
369
- content: "Follow-up message...",
434
+ const stats = await client.support.getStats(orgId);
435
+ const detail = await client.support.getTicket(orgId, ticket.id);
436
+ await client.support.addMessage(orgId, ticket.id, "Follow-up message...");
437
+ await client.support.updateStatus(orgId, ticket.id, "resolved");
438
+ ```
439
+
440
+ ### RPC (`client.rpc`)
441
+
442
+ ```typescript
443
+ const gateway = new IteradianClient({ apiKey: "itrd_live_..." });
444
+ const networks = await gateway.rpc.networks();
445
+ const res = await gateway.rpc.call("eth-mainnet", {
446
+ jsonrpc: "2.0",
447
+ method: "eth_blockNumber",
448
+ params: [],
449
+ id: 1,
370
450
  });
451
+ const batch = await gateway.rpc.batch("eth-mainnet", [
452
+ { jsonrpc: "2.0", method: "eth_blockNumber", params: [], id: 1 },
453
+ { jsonrpc: "2.0", method: "eth_chainId", params: [], id: 2 },
454
+ ]);
371
455
  ```
372
456
 
373
457
  ## Type Definitions
374
458
 
375
- All types are exported from the package and defined in `src/types.ts` (538 lines):
459
+ All types are exported from the package and defined in `src/types.ts`. Response fields are optional except `id`; decimal
460
+ fields are typed `number | string` (`Numeric`):
376
461
 
377
462
  ### Configuration
378
463
 
@@ -382,70 +467,75 @@ All types are exported from the package and defined in `src/types.ts` (538 lines
382
467
 
383
468
  ### Auth Types
384
469
 
385
- | Type | Fields |
386
- | ----------------- | ------------------------------------- |
387
- | `LoginRequest` | `email`, `password`, `twoFactorCode?` |
388
- | `RegisterRequest` | `email`, `password` |
389
- | `RegisterResponse` | `message`, `email` (no tokens) |
390
- | `AuthTokens` | `accessToken`, `refreshToken`, `user` |
391
- | `TwoFASetup` | `secret`, `qrCode` |
470
+ | Type | Fields |
471
+ | ------------------ | ------------------------------------------------------------------- |
472
+ | `LoginRequest` | `email`, `password`, `twoFactorCode?`, `backupCode?` |
473
+ | `RegisterRequest` | `email`, `password`, `acceptedTerms` |
474
+ | `RegisterResponse` | `message`, `email` (no tokens) |
475
+ | `LoginResult` | `accessToken?`, `refreshToken?`, `user?`, `requires2FA?` |
476
+ | `AuthTokens` | `accessToken`, `refreshToken`, `user?` (refresh) |
477
+ | `TwoFASetup` | `secret`, `qrCode` |
392
478
 
393
479
  ### Organization Types
394
480
 
395
- | Type | Fields |
396
- | --------------------- | ---------------------------------------------- |
397
- | `Organization` | `id`, `name`, `slug`, `createdAt`, `updatedAt` |
398
- | `OrgMember` | `id`, `userId`, `email`, `role`, `joinedAt` |
399
- | `CreateOrgRequest` | `name`, `slug` |
400
- | `InviteMemberRequest` | `email`, `role` |
401
- | `OrgInvite` | `id`, `email`, `role`, `status`, `expiresAt`, `createdAt`, `invitedBy?` |
402
- | `MyInvites` | `emailVerified`, `invites` (`MyInvite[]`) |
403
- | `InviteAcceptance` | `organizationId`, `membershipId`, `role` |
481
+ | Type | Fields |
482
+ | --------------------------- | ----------------------------------------------------------------------- |
483
+ | `Organization` | `id`, `name?`, `slug?`, `role?`, `subscription?`, `members?` |
484
+ | `OrgMember` | `id`, `userId?`, `email?`, `role?`, `joinedAt?` |
485
+ | `CreateOrganizationRequest` | `name`, `planId`, `acceptedTerms`, `slug?`, `billingInterval?` |
486
+ | `OrgInvite` | `id`, `email?`, `role?`, `status?`, `expiresAt?`, `createdAt?`, `invitedBy?` |
487
+ | `MyInvites` | `emailVerified?`, `invites` (`MyInvite[]`) |
488
+ | `InviteAcceptance` | `organizationId?`, `membershipId?`, `role?` |
404
489
 
405
490
  ### API Key Types
406
491
 
407
- | Type | Fields |
408
- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
409
- | `ApiKey` | `id`, `name`, `prefix`, `key?`, `environment`, `status`, `ipAllowlist?`, `allowedNetworks?`, `rateLimit?`, `dailyLimit?`, `createdAt`, `updatedAt`, `expiresAt?`, `lastUsedAt?` |
410
- | `CreateApiKeyRequest` | `name`, `environment`, `ipAllowlist?`, `allowedNetworks?`, `rateLimit?`, `dailyLimit?`, `expiresAt?` |
492
+ | Type | Fields |
493
+ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
494
+ | `ApiKey` | `id`, `name?`, `prefix?`, `environment?`, `status?`, `ipAllowlist?`, `allowedNetworks?`, `rateLimit?`, `dailyLimit?`, `expiresAt?`, `lastUsedAt?`, `createdAt?` |
495
+ | `ApiKeyWithSecret` | `ApiKey` plus `secret` (create and rotate) and `key` (deprecated alias of `secret`) |
496
+ | `CreateApiKeyRequest` | `name`, `environment`, `ipAllowlist?`, `allowedNetworks?`, `rateLimit?`, `dailyLimit?`, `expiresAt?`, `walletUrlAuth?` |
411
497
 
412
498
  ### Network & Endpoint Types
413
499
 
414
- | Type | Fields |
415
- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
416
- | `Network` | `id`, `slug`, `name`, `chainId`, `type`, `environment`, `isActive` |
417
- | `Endpoint` | `id`, `organizationId`, `networkId`, `region`, `name`, `priority`, `status`, `isEnabled`, `timeoutMs`, `retryCount`, metrics |
418
- | `CreateEndpointRequest` | `name`, `networkId`, `region`, `priority?`, `timeoutMs?`, `retryCount?` |
500
+ | Type | Fields |
501
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
502
+ | `Network` | `id`, `name?`, `chainId?`, `type?`, `environment?`, `nativeCurrency?`, `isActive?` |
503
+ | `Endpoint` | `id`, `networkId?`, `region?`, `name?`, `priority?`, `status?`, `isEnabled?`, `timeoutMs?`, `retryCount?`, metrics |
504
+ | `CreateEndpointRequest` | `name`, `networkId`, `region`, `priority?`, `timeoutMs?`, `retryCount?`, `rateLimitOverride?` |
505
+ | `EndpointHealth` | `status?`, `nodeCount?`, `healthyNodeCount?`, `latencyMs?`, `lastCheck?` |
419
506
 
420
507
  ### Logging Types
421
508
 
422
- | Type | Fields |
423
- | ---------------- | ----------------------------------------------------------------------------------------------------------- |
424
- | `RequestLog` | `id`, `organizationId`, `method`, `status`, `statusCode?`, `latencyMs?`, `network?`, `region?`, `timestamp` |
425
- | `LogsResponse` | `logs`, `total`, `page`, `pageSize`, `totalPages` |
426
- | `LogQueryParams` | `page?`, `pageSize?`, `status?`, `method?`, `network?`, `region?`, `from?`, `to?`, `sortBy?`, `sortOrder?` |
509
+ | Type | Fields |
510
+ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
511
+ | `RequestLog` | `id`, `method?`, `status?`, `statusCode?`, `latencyMs?`, `network?`, `region?`, `timestamp?` |
512
+ | `LogsResponse` | `logs`, `total?`, `stats?` |
513
+ | `LogQueryParams` | `limit?`, `offset?`, `status?`, `method?`, `apiKeyId?`, `network?`, `region?`, `search?`, `statusCode?`, `minLatencyMs?`, `maxLatencyMs?`, `from?`, `to?`, `sortBy?`, `sortOrder?` |
427
514
 
428
515
  ### Alert Types
429
516
 
430
- | Type | Fields |
431
- | ------------------------ | -------------------------------------------------------------------------------------------------------------- |
432
- | `Alert` | `id`, `organizationId`, `ruleId?`, `severity`, `status`, `title`, `message`, `metadata?` |
433
- | `AlertRule` | `id`, `organizationId`, `name`, `metric`, `condition`, `threshold`, `severity`, `isEnabled`, `cooldownMinutes` |
434
- | `CreateAlertRuleRequest` | `name`, `metric`, `condition`, `threshold`, `severity`, `isEnabled`, `cooldownMinutes` |
517
+ | Type | Fields |
518
+ | -------------------------- | -------------------------------------------------------------------------------------------- |
519
+ | `Alert` | `id`, `ruleId?`, `type?`, `severity?`, `status?`, `title?`, `message?`, `firedAt?`, `metadata?` |
520
+ | `AlertRule` | `id`, `name?`, `type?`, `severity?`, `isEnabled?`, `config?`, `cooldownSeconds?` |
521
+ | `CreateAlertRuleRequest` | `name`, `type`, `config`, `severity?`, `cooldownSeconds?`, `isEnabled?` |
522
+ | `AlertChannel` | `id`, `name?`, `type?`, `isEnabled?`, `config?` |
523
+ | `CreateAlertChannelRequest` | `name`, `type`, `config`, `isEnabled?` |
435
524
 
436
525
  ### Billing Types
437
526
 
438
- | Type | Fields |
439
- | -------------- | --------------------------------------------------------------------------------------- |
440
- | `Plan` | `id`, `name`, `slug`, `price`, `currency`, `interval`, `features`, `limits`, `isActive` |
441
- | `Subscription` | `id`, `organizationId`, `planId`, `status`, `cancelAtPeriodEnd`, `plan?` |
527
+ | Type | Fields |
528
+ | -------------- | ------------------------------------------------------------------------------------------------------- |
529
+ | `Plan` | `id`, `name?`, `displayName?`, `priceMonthly?`, `limits?`, `features?`, `isActive?` |
530
+ | `Subscription` | `id`, `status?`, `plan?`, `billingInterval?`, `currentPeriodEnd?`, `cancelAtPeriodEnd?`, `recentInvoices?` |
442
531
 
443
532
  ### Support Types
444
533
 
445
- | Type | Fields |
446
- | --------------------- | ------------------------------------------------------------------- |
447
- | `SupportTicket` | `id`, `organizationId`, `subject`, `category`, `priority`, `status` |
448
- | `CreateTicketRequest` | `subject`, `category`, `priority`, `message` |
534
+ | Type | Fields |
535
+ | --------------------- | ------------------------------------------------------------------------------ |
536
+ | `SupportTicket` | `id`, `subject?`, `category?`, `priority?`, `status?`, `messages?`, `createdBy?` |
537
+ | `CreateTicketRequest` | `subject`, `body`, `category?`, `priority?` |
538
+ | `TicketMessage` | `id`, `body?`, `isStaff?`, `author?`, `createdAt?` |
449
539
 
450
540
  ### Error Types
451
541
 
@@ -465,7 +555,7 @@ try {
465
555
  } catch (err) {
466
556
  if (err instanceof IteradianError) {
467
557
  console.log(`Status: ${err.statusCode}`); // 401
468
- console.log(`Message: ${err.message}`); // "Invalid credentials"
558
+ console.log(`Message: ${err.message}`); // "Invalid credentials" (validation errors: messages joined with ", ")
469
559
  console.log(`Error: ${err.error}`); // Error code
470
560
  } else {
471
561
  console.log(`Unexpected error: ${err}`);