@drip-sdk/node 1.1.0 → 1.1.2

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/dist/index.d.cts CHANGED
@@ -68,7 +68,7 @@ interface StreamMeterFlushResult {
68
68
  /** The charge result from the API (if quantity > 0) */
69
69
  charge: ChargeResult['charge'] | null;
70
70
  /** Whether this was an idempotent replay */
71
- isReplay: boolean;
71
+ isDuplicate: boolean;
72
72
  }
73
73
  /**
74
74
  * Internal charge function type (injected by Drip class).
@@ -498,17 +498,29 @@ interface RetryOptions {
498
498
  }
499
499
  /**
500
500
  * Configuration options for the Drip SDK client.
501
+ *
502
+ * All fields are optional - the SDK will read from environment variables:
503
+ * - `DRIP_API_KEY` - Your Drip API key
504
+ * - `DRIP_BASE_URL` - Override API base URL (optional)
501
505
  */
502
506
  interface DripConfig {
503
507
  /**
504
508
  * Your Drip API key. Obtain this from the Drip dashboard.
505
- * @example "drip_live_abc123..."
509
+ * Falls back to `DRIP_API_KEY` environment variable if not provided.
510
+ *
511
+ * Supports both key types:
512
+ * - **Secret keys** (`sk_live_...` / `sk_test_...`): Full access to all endpoints
513
+ * - **Public keys** (`pk_live_...` / `pk_test_...`): Safe for client-side use.
514
+ * Can access usage, customers, charges, sessions, analytics, etc.
515
+ * Cannot access webhook management, API key management, or feature flags.
516
+ *
517
+ * @example "sk_live_abc123..." or "pk_live_abc123..."
506
518
  */
507
- apiKey: string;
519
+ apiKey?: string;
508
520
  /**
509
521
  * Base URL for the Drip API. Defaults to production API.
510
- * Override for staging/development environments.
511
- * @default "https://api.drip.dev/v1"
522
+ * Falls back to `DRIP_BASE_URL` environment variable if not provided.
523
+ * @default "https://drip-app-hlunj.ondigitalocean.app/v1"
512
524
  */
513
525
  baseUrl?: string;
514
526
  /**
@@ -553,14 +565,21 @@ interface DripConfig {
553
565
  interface CreateCustomerParams {
554
566
  /**
555
567
  * Your internal customer/user ID for reconciliation.
568
+ * At least one of `externalCustomerId` or `onchainAddress` is required.
556
569
  * @example "user_12345"
557
570
  */
558
571
  externalCustomerId?: string;
559
572
  /**
560
573
  * The customer's Drip Smart Account address (derived from their EOA).
574
+ * At least one of `externalCustomerId` or `onchainAddress` is required.
561
575
  * @example "0x1234567890abcdef..."
562
576
  */
563
- onchainAddress: string;
577
+ onchainAddress?: string;
578
+ /**
579
+ * Whether this customer is internal-only (usage tracked but not billed).
580
+ * @default false
581
+ */
582
+ isInternal?: boolean;
564
583
  /**
565
584
  * Additional metadata to store with the customer.
566
585
  */
@@ -576,8 +595,12 @@ interface Customer {
576
595
  businessId?: string;
577
596
  /** Your external customer ID (if provided) */
578
597
  externalCustomerId: string | null;
579
- /** Customer's on-chain address */
580
- onchainAddress: string;
598
+ /** Customer's on-chain address (null for internal-only customers) */
599
+ onchainAddress: string | null;
600
+ /** Whether this customer is internal-only (usage tracked but not billed) */
601
+ isInternal: boolean;
602
+ /** Customer status */
603
+ status: 'ACTIVE' | 'LOW_BALANCE' | 'PAUSED';
581
604
  /** Custom metadata */
582
605
  metadata: Record<string, unknown> | null;
583
606
  /** ISO timestamp of creation */
@@ -645,8 +668,8 @@ interface ChargeParams {
645
668
  */
646
669
  quantity: number;
647
670
  /**
648
- * Unique key to prevent duplicate charges.
649
- * If provided, retrying with the same key returns the original charge.
671
+ * Unique key to prevent duplicate charges and map each call to a single event.
672
+ * Auto-generated if not provided. Retrying with the same key returns the original charge.
650
673
  * @example "req_abc123"
651
674
  */
652
675
  idempotencyKey?: string;
@@ -663,8 +686,8 @@ interface ChargeResult {
663
686
  success: boolean;
664
687
  /** The usage event ID */
665
688
  usageEventId: string;
666
- /** True if this was an idempotent replay (returned cached result from previous request) */
667
- isReplay: boolean;
689
+ /** True if this was a deduplicated replay (returned cached result from previous request) */
690
+ isDuplicate: boolean;
668
691
  /** Details about the charge */
669
692
  charge: {
670
693
  /** Unique charge ID */
@@ -682,7 +705,7 @@ interface ChargeResult {
682
705
  /**
683
706
  * Possible charge statuses.
684
707
  */
685
- type ChargeStatus = 'PENDING' | 'SUBMITTED' | 'CONFIRMED' | 'FAILED' | 'REFUNDED';
708
+ type ChargeStatus = 'PENDING' | 'PENDING_SETTLEMENT' | 'CONFIRMED' | 'FAILED' | 'REFUNDED';
686
709
  /**
687
710
  * Parameters for tracking usage without billing.
688
711
  * Use this for internal visibility, pilots, or pre-billing tracking.
@@ -847,16 +870,22 @@ interface Webhook {
847
870
  description: string | null;
848
871
  /** Whether the webhook is active */
849
872
  isActive: boolean;
873
+ /** Health status of the webhook endpoint */
874
+ healthStatus: 'HEALTHY' | 'DEGRADED' | 'UNHEALTHY';
875
+ /** Number of consecutive delivery failures */
876
+ consecutiveFailures: number;
877
+ /** ISO timestamp of last health status change */
878
+ lastHealthChange: string | null;
850
879
  /** ISO timestamp of creation */
851
880
  createdAt: string;
852
881
  /** ISO timestamp of last update */
853
882
  updatedAt: string;
854
883
  /** Delivery statistics */
855
884
  stats?: {
856
- totalDeliveries: number;
857
- successfulDeliveries: number;
858
- failedDeliveries: number;
859
- lastDeliveryAt: string | null;
885
+ total: number;
886
+ delivered: number;
887
+ failed: number;
888
+ pending: number;
860
889
  };
861
890
  }
862
891
  /**
@@ -944,7 +973,7 @@ interface CreateWorkflowParams {
944
973
  /** URL-safe identifier (lowercase alphanumeric with underscores/hyphens) */
945
974
  slug: string;
946
975
  /** Type of workflow */
947
- productSurface?: 'RPC' | 'WEBHOOK' | 'AGENT' | 'PIPELINE' | 'CUSTOM';
976
+ productSurface?: 'API' | 'RPC' | 'WEBHOOK' | 'AGENT' | 'PIPELINE' | 'CUSTOM';
948
977
  /** Optional description */
949
978
  description?: string;
950
979
  /** Additional metadata */
@@ -958,6 +987,8 @@ interface Workflow {
958
987
  name: string;
959
988
  slug: string;
960
989
  productSurface: string;
990
+ /** Blockchain chain (if applicable) */
991
+ chain: string | null;
961
992
  description: string | null;
962
993
  isActive: boolean;
963
994
  createdAt: string;
@@ -1231,47 +1262,93 @@ interface RecordRunResult {
1231
1262
  summary: string;
1232
1263
  }
1233
1264
  /**
1234
- * Full run timeline response.
1265
+ * Full run timeline response from GET /runs/:id/timeline.
1235
1266
  */
1236
1267
  interface RunTimeline {
1237
- run: {
1238
- id: string;
1239
- customerId: string;
1240
- customerName: string | null;
1241
- workflowId: string;
1242
- workflowName: string;
1243
- status: RunStatus;
1244
- startedAt: string | null;
1245
- endedAt: string | null;
1246
- durationMs: number | null;
1247
- errorMessage: string | null;
1248
- errorCode: string | null;
1249
- correlationId: string | null;
1250
- metadata: Record<string, unknown> | null;
1251
- };
1252
- timeline: Array<{
1268
+ runId: string;
1269
+ workflowId: string | null;
1270
+ workflowName: string | null;
1271
+ customerId: string;
1272
+ status: RunStatus;
1273
+ correlationId: string | null;
1274
+ metadata: Record<string, unknown> | null;
1275
+ errorMessage: string | null;
1276
+ errorCode: string | null;
1277
+ startedAt: string | null;
1278
+ endedAt: string | null;
1279
+ durationMs: number | null;
1280
+ events: Array<{
1253
1281
  id: string;
1254
1282
  eventType: string;
1255
- quantity: number;
1256
- units: string | null;
1283
+ actionName: string | null;
1284
+ outcome: 'SUCCESS' | 'FAILED' | 'PENDING' | 'TIMEOUT' | 'RETRYING';
1285
+ explanation: string | null;
1257
1286
  description: string | null;
1258
- costUnits: number | null;
1259
1287
  timestamp: string;
1260
- correlationId: string | null;
1288
+ durationMs: number | null;
1261
1289
  parentEventId: string | null;
1262
- charge: {
1263
- id: string;
1264
- amountUsdc: string;
1265
- status: string;
1290
+ retryOfEventId: string | null;
1291
+ attemptNumber: number;
1292
+ retriedByEventId: string | null;
1293
+ costUsdc: string | null;
1294
+ isRetry: boolean;
1295
+ retryChain: {
1296
+ totalAttempts: number;
1297
+ finalOutcome: string;
1298
+ events: string[];
1299
+ } | null;
1300
+ metadata: {
1301
+ usageType: string;
1302
+ quantity: number;
1303
+ units: string | null;
1266
1304
  } | null;
1267
1305
  }>;
1306
+ anomalies: Array<{
1307
+ id: string;
1308
+ type: string;
1309
+ severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
1310
+ title: string;
1311
+ explanation: string;
1312
+ relatedEventIds: string[];
1313
+ detectedAt: string;
1314
+ status: 'OPEN' | 'INVESTIGATING' | 'RESOLVED' | 'FALSE_POSITIVE' | 'IGNORED';
1315
+ }>;
1316
+ summary: {
1317
+ totalEvents: number;
1318
+ byType: Record<string, number>;
1319
+ byOutcome: Record<string, number>;
1320
+ retriedEvents: number;
1321
+ failedEvents: number;
1322
+ totalCostUsdc: string | null;
1323
+ };
1324
+ hasMore: boolean;
1325
+ nextCursor: string | null;
1326
+ }
1327
+ /**
1328
+ * Run details response from GET /runs/:id.
1329
+ */
1330
+ interface RunDetails {
1331
+ id: string;
1332
+ customerId: string;
1333
+ customerName: string | null;
1334
+ workflowId: string;
1335
+ workflowName: string;
1336
+ status: RunStatus;
1337
+ startedAt: string | null;
1338
+ endedAt: string | null;
1339
+ durationMs: number | null;
1340
+ errorMessage: string | null;
1341
+ errorCode: string | null;
1342
+ correlationId: string | null;
1343
+ metadata: Record<string, unknown> | null;
1268
1344
  totals: {
1269
1345
  eventCount: number;
1270
1346
  totalQuantity: string;
1271
1347
  totalCostUnits: string;
1272
- totalChargedUsdc: string;
1273
1348
  };
1274
- summary: string;
1349
+ _links: {
1350
+ timeline: string;
1351
+ };
1275
1352
  }
1276
1353
  /**
1277
1354
  * Parameters for wrapping an external API call with usage tracking.
@@ -1376,6 +1453,14 @@ declare class Drip {
1376
1453
  private readonly baseUrl;
1377
1454
  private readonly timeout;
1378
1455
  private readonly resilience;
1456
+ /**
1457
+ * The type of API key being used.
1458
+ *
1459
+ * - `'secret'` — Full access (sk_live_... / sk_test_...)
1460
+ * - `'public'` — Client-safe, restricted access (pk_live_... / pk_test_...)
1461
+ * - `'unknown'` — Key format not recognized (legacy or custom)
1462
+ */
1463
+ readonly keyType: 'secret' | 'public' | 'unknown';
1379
1464
  /**
1380
1465
  * Creates a new Drip SDK client.
1381
1466
  *
@@ -1386,23 +1471,29 @@ declare class Drip {
1386
1471
  * ```typescript
1387
1472
  * // Basic usage
1388
1473
  * const drip = new Drip({
1389
- * apiKey: 'drip_live_abc123...',
1474
+ * apiKey: 'sk_live_...',
1390
1475
  * });
1391
1476
  *
1392
1477
  * // With production resilience (recommended)
1393
1478
  * const drip = new Drip({
1394
- * apiKey: 'drip_live_abc123...',
1479
+ * apiKey: 'sk_live_...',
1395
1480
  * resilience: true,
1396
1481
  * });
1397
1482
  *
1398
1483
  * // High throughput mode
1399
1484
  * const drip = new Drip({
1400
- * apiKey: 'drip_live_abc123...',
1485
+ * apiKey: 'sk_live_...',
1401
1486
  * resilience: 'high-throughput',
1402
1487
  * });
1403
1488
  * ```
1404
1489
  */
1405
- constructor(config: DripConfig);
1490
+ constructor(config?: DripConfig);
1491
+ /**
1492
+ * Asserts that the SDK was initialized with a secret key (sk_).
1493
+ * Throws a clear error if a public key is being used for a secret-key-only operation.
1494
+ * @internal
1495
+ */
1496
+ private assertSecretKey;
1406
1497
  /**
1407
1498
  * Makes an authenticated request to the Drip API.
1408
1499
  * @internal
@@ -1720,8 +1811,11 @@ declare class Drip {
1720
1811
  * ```
1721
1812
  */
1722
1813
  getChargeStatus(chargeId: string): Promise<{
1814
+ id: string;
1723
1815
  status: ChargeStatus;
1724
- txHash?: string;
1816
+ txHash: string | null;
1817
+ confirmedAt: string | null;
1818
+ failureReason: string | null;
1725
1819
  }>;
1726
1820
  /**
1727
1821
  * Creates a checkout session to add funds to a customer's account.
@@ -1874,8 +1968,8 @@ declare class Drip {
1874
1968
  * @example
1875
1969
  * ```typescript
1876
1970
  * const workflow = await drip.createWorkflow({
1877
- * name: 'Prescription Intake',
1878
- * slug: 'prescription_intake',
1971
+ * name: 'Document Processing',
1972
+ * slug: 'doc_processing',
1879
1973
  * productSurface: 'AGENT',
1880
1974
  * });
1881
1975
  * ```
@@ -1940,33 +2034,53 @@ declare class Drip {
1940
2034
  totalCostUnits: string | null;
1941
2035
  }>;
1942
2036
  /**
1943
- * Gets a run's full timeline with events and computed totals.
2037
+ * Gets run details with summary totals.
2038
+ *
2039
+ * For full event history with retry chains and anomalies, use `getRunTimeline()`.
2040
+ *
2041
+ * @param runId - The run ID
2042
+ * @returns Run details with totals
2043
+ *
2044
+ * @example
2045
+ * ```typescript
2046
+ * const run = await drip.getRun('run_abc123');
2047
+ * console.log(`Status: ${run.status}, Events: ${run.totals.eventCount}`);
2048
+ * ```
2049
+ */
2050
+ getRun(runId: string): Promise<RunDetails>;
2051
+ /**
2052
+ * Gets a run's full timeline with events, anomalies, and analytics.
1944
2053
  *
1945
2054
  * This is the key endpoint for debugging "what happened" in an execution.
1946
2055
  *
1947
2056
  * @param runId - The run ID
1948
- * @returns Full timeline with events and summary
2057
+ * @param options - Pagination and filtering options
2058
+ * @returns Full timeline with events, anomalies, and summary
1949
2059
  *
1950
2060
  * @example
1951
2061
  * ```typescript
1952
- * const { run, timeline, totals, summary } = await drip.getRunTimeline('run_abc123');
2062
+ * const timeline = await drip.getRunTimeline('run_abc123');
1953
2063
  *
1954
- * console.log(`Status: ${run.status}`);
1955
- * console.log(`Summary: ${summary}`);
1956
- * console.log(`Total cost: ${totals.totalCostUnits}`);
2064
+ * console.log(`Status: ${timeline.status}`);
2065
+ * console.log(`Events: ${timeline.summary.totalEvents}`);
1957
2066
  *
1958
- * for (const event of timeline) {
1959
- * console.log(`${event.eventType}: ${event.quantity} ${event.units}`);
2067
+ * for (const event of timeline.events) {
2068
+ * console.log(`${event.eventType}: ${event.outcome}`);
1960
2069
  * }
1961
2070
  * ```
1962
2071
  */
1963
- getRunTimeline(runId: string): Promise<RunTimeline>;
2072
+ getRunTimeline(runId: string, options?: {
2073
+ limit?: number;
2074
+ cursor?: string;
2075
+ includeAnomalies?: boolean;
2076
+ collapseRetries?: boolean;
2077
+ }): Promise<RunTimeline>;
1964
2078
  /**
1965
2079
  * Emits an event to a run.
1966
2080
  *
1967
- * Events can be stored idempotently when an `idempotencyKey` is provided.
2081
+ * Each event is assigned a unique idempotency key (auto-generated if not provided).
2082
+ * This maps each inference or API call to a single trackable event.
1968
2083
  * Use `Drip.generateIdempotencyKey()` for deterministic key generation.
1969
- * If `idempotencyKey` is omitted, repeated calls may create duplicate events.
1970
2084
  *
1971
2085
  * @param params - Event parameters
1972
2086
  * @returns The created event
@@ -2007,10 +2121,13 @@ declare class Drip {
2007
2121
  success: boolean;
2008
2122
  created: number;
2009
2123
  duplicates: number;
2124
+ skipped: number;
2010
2125
  events: Array<{
2011
2126
  id: string;
2012
2127
  eventType: string;
2013
2128
  isDuplicate: boolean;
2129
+ skipped?: boolean;
2130
+ reason?: string;
2014
2131
  }>;
2015
2132
  }>;
2016
2133
  /**
@@ -2135,7 +2252,7 @@ declare class Drip {
2135
2252
  * // Record a complete agent run in one call
2136
2253
  * const result = await drip.recordRun({
2137
2254
  * customerId: 'cust_123',
2138
- * workflow: 'prescription_intake', // Auto-creates if doesn't exist
2255
+ * workflow: 'doc_processing', // Auto-creates if doesn't exist
2139
2256
  * events: [
2140
2257
  * { eventType: 'agent.start', description: 'Started processing' },
2141
2258
  * { eventType: 'tool.ocr', quantity: 3, units: 'pages', costUnits: 0.15 },
@@ -2154,7 +2271,7 @@ declare class Drip {
2154
2271
  * // Record a failed run with error details
2155
2272
  * const result = await drip.recordRun({
2156
2273
  * customerId: 'cust_123',
2157
- * workflow: 'prescription_intake',
2274
+ * workflow: 'doc_processing',
2158
2275
  * events: [
2159
2276
  * { eventType: 'agent.start', description: 'Started processing' },
2160
2277
  * { eventType: 'tool.ocr', quantity: 1, units: 'pages' },
@@ -2167,6 +2284,11 @@ declare class Drip {
2167
2284
  * ```
2168
2285
  */
2169
2286
  recordRun(params: RecordRunParams): Promise<RecordRunResult>;
2287
+ /**
2288
+ * 4-step orchestration fallback for servers without POST /runs/record.
2289
+ * @internal
2290
+ */
2291
+ private _recordRunFallback;
2170
2292
  /**
2171
2293
  * Generates a deterministic idempotency key.
2172
2294
  *
@@ -2326,6 +2448,33 @@ declare class Drip {
2326
2448
  createStreamMeter(options: StreamMeterOptions): StreamMeter;
2327
2449
  }
2328
2450
 
2451
+ /**
2452
+ * Pre-initialized Drip client singleton.
2453
+ *
2454
+ * Uses lazy initialization - only creates the client when first accessed.
2455
+ * Reads `DRIP_API_KEY` from environment variables.
2456
+ *
2457
+ * @example
2458
+ * ```typescript
2459
+ * import { drip } from '@drip-sdk/node';
2460
+ *
2461
+ * // Track usage with one line
2462
+ * await drip.trackUsage({ customerId: 'cust_123', meter: 'api_calls', quantity: 1 });
2463
+ *
2464
+ * // Charge with one line
2465
+ * await drip.charge({ customerId: 'cust_123', meter: 'api_calls', quantity: 1 });
2466
+ *
2467
+ * // Record a run
2468
+ * await drip.recordRun({
2469
+ * customerId: 'cust_123',
2470
+ * workflow: 'agent-run',
2471
+ * events: [{ eventType: 'llm.call', quantity: 1000, units: 'tokens' }],
2472
+ * status: 'COMPLETED',
2473
+ * });
2474
+ * ```
2475
+ */
2476
+ declare const drip: Drip;
2477
+
2329
2478
  // @ts-ignore
2330
2479
  export = Drip;
2331
- export { type BalanceResult, type Charge, type ChargeParams, type ChargeResult, type ChargeStatus, type CheckoutParams, type CheckoutResult, CircuitBreaker, type CircuitBreakerConfig, CircuitBreakerOpenError, type CircuitState, type CostEstimateLineItem, type CostEstimateResponse, type CreateCustomerParams, type CreateWebhookParams, type CreateWebhookResponse, type CreateWorkflowParams, type CustomPricing, type Customer, type DeleteWebhookResponse, Drip, type DripConfig, DripError, type EmitEventParams, type EndRunParams, type EstimateFromHypotheticalParams, type EstimateFromUsageParams, type EventResult, type HypotheticalUsageItem, type ListChargesOptions, type ListChargesResponse, type ListCustomersOptions, type ListCustomersResponse, type ListMetersResponse, type ListWebhooksResponse, type Meter, MetricsCollector, type MetricsSummary, RateLimiter, type RateLimiterConfig, type RecordRunEvent, type RecordRunParams, type RecordRunResult, type RequestMetrics, type ResilienceConfig, type ResilienceHealth, ResilienceManager, type RetryConfig, RetryExhaustedError, type RetryOptions, type RunResult, type RunStatus, type RunTimeline, type StartRunParams, StreamMeter, type StreamMeterFlushResult, type StreamMeterOptions, type TrackUsageParams, type TrackUsageResult, type Webhook, type WebhookEventType, type Workflow, type WrapApiCallParams, type WrapApiCallResult, calculateBackoff, createDefaultResilienceConfig, createDisabledResilienceConfig, createHighThroughputResilienceConfig, isRetryableError };
2480
+ export { type BalanceResult, type Charge, type ChargeParams, type ChargeResult, type ChargeStatus, type CheckoutParams, type CheckoutResult, CircuitBreaker, type CircuitBreakerConfig, CircuitBreakerOpenError, type CircuitState, type CostEstimateLineItem, type CostEstimateResponse, type CreateCustomerParams, type CreateWebhookParams, type CreateWebhookResponse, type CreateWorkflowParams, type CustomPricing, type Customer, type DeleteWebhookResponse, Drip, type DripConfig, DripError, type EmitEventParams, type EndRunParams, type EstimateFromHypotheticalParams, type EstimateFromUsageParams, type EventResult, type HypotheticalUsageItem, type ListChargesOptions, type ListChargesResponse, type ListCustomersOptions, type ListCustomersResponse, type ListMetersResponse, type ListWebhooksResponse, type Meter, MetricsCollector, type MetricsSummary, RateLimiter, type RateLimiterConfig, type RecordRunEvent, type RecordRunParams, type RecordRunResult, type RequestMetrics, type ResilienceConfig, type ResilienceHealth, ResilienceManager, type RetryConfig, RetryExhaustedError, type RetryOptions, type RunDetails, type RunResult, type RunStatus, type RunTimeline, type StartRunParams, StreamMeter, type StreamMeterFlushResult, type StreamMeterOptions, type TrackUsageParams, type TrackUsageResult, type Webhook, type WebhookEventType, type Workflow, type WrapApiCallParams, type WrapApiCallResult, calculateBackoff, createDefaultResilienceConfig, createDisabledResilienceConfig, createHighThroughputResilienceConfig, drip, isRetryableError };