@layervai/qurl 0.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.
@@ -0,0 +1,765 @@
1
+ type OpenString<T extends string> = T | (string & {});
2
+ /** Common response metadata returned by the API envelope. */
3
+ export interface Meta {
4
+ request_id?: string;
5
+ page_size?: number;
6
+ has_more?: boolean;
7
+ next_cursor?: string;
8
+ tombstone?: TombstoneInfo;
9
+ }
10
+ /** Read-only metadata returned on tombstoned-resource error envelopes. */
11
+ export interface TombstoneInfo {
12
+ tombstoned_at: string;
13
+ final_access_count?: number;
14
+ }
15
+ /** Shared pagination fields the SDK flattens out of response `meta`. */
16
+ export interface PaginatedOutput {
17
+ next_cursor?: string;
18
+ has_more: boolean;
19
+ request_id?: string;
20
+ page_size?: number;
21
+ }
22
+ /** Resource type values currently advertised by the API. */
23
+ export type ResourceType = OpenString<"url" | "tunnel" | "transit">;
24
+ /** A well-known AI agent category identifier. */
25
+ export type AIAgentCategory = OpenString<"chatgpt" | "gptbot" | "claude" | "gemini" | "perplexity" | "cohere" | "meta" | "bytedance" | "amazon" | "apple" | "commoncrawl" | "mistral" | "generic_ai">;
26
+ /** AI agent access control policy. */
27
+ export interface AIAgentPolicy {
28
+ block_all?: boolean;
29
+ deny_categories?: AIAgentCategory[];
30
+ allow_categories?: AIAgentCategory[];
31
+ }
32
+ /** Access control policy for a qURL. */
33
+ export interface AccessPolicy {
34
+ ip_allowlist?: string[];
35
+ ip_denylist?: string[];
36
+ geo_allowlist?: string[];
37
+ geo_denylist?: string[];
38
+ user_agent_allow_regex?: string;
39
+ user_agent_deny_regex?: string;
40
+ ai_agent_policy?: AIAgentPolicy;
41
+ }
42
+ /** An individual access token within a qURL resource. */
43
+ export interface AccessToken {
44
+ /** Display identifier for this token (q_ prefix). */
45
+ qurl_id: string;
46
+ label?: string;
47
+ status: "active" | "consumed" | "expired" | "revoked";
48
+ one_time_use: boolean;
49
+ max_sessions: number;
50
+ /**
51
+ * Session lifetime in seconds. The corresponding input fields take a
52
+ * human-readable duration string like `"1h"`; the API returns seconds.
53
+ */
54
+ session_duration: number;
55
+ access_policy?: AccessPolicy;
56
+ use_count: number;
57
+ qurl_site?: string;
58
+ created_at: string;
59
+ expires_at: string;
60
+ }
61
+ /** Per-qURL summary returned from resource-detail and token-update endpoints. */
62
+ export interface QurlSummary {
63
+ qurl_id?: string;
64
+ label?: string;
65
+ status?: "active" | "consumed" | "expired" | "revoked";
66
+ one_time_use?: boolean;
67
+ max_sessions?: number;
68
+ /** Session lifetime in seconds. */
69
+ session_duration?: number;
70
+ access_policy?: AccessPolicy;
71
+ use_count?: number;
72
+ qurl_site?: string;
73
+ created_at?: string;
74
+ expires_at?: string;
75
+ }
76
+ /**
77
+ * A qURL resource as returned by the legacy `/v1/qurls` management surface.
78
+ *
79
+ * `qurl_link` is delivered exactly once on create/mint responses and is not
80
+ * recoverable from read-side shapes. Persist it at create or mint time.
81
+ */
82
+ export interface QURL {
83
+ resource_id: string;
84
+ type?: ResourceType;
85
+ target_url: string;
86
+ status: "active" | "revoked";
87
+ description?: string;
88
+ tags?: string[];
89
+ /**
90
+ * The custom hostname this resource is reachable under, or `null` when no
91
+ * custom domain is configured. Read shapes use `string | null`; write shapes
92
+ * use `string | undefined` because JSON `null` and an absent field have
93
+ * different semantics.
94
+ */
95
+ custom_domain?: string | null;
96
+ slug?: string;
97
+ qurl_site?: string;
98
+ qurl_count?: number;
99
+ access_tokens?: AccessToken[];
100
+ created_at: string;
101
+ expires_at?: string;
102
+ }
103
+ /**
104
+ * Input for creating a qURL.
105
+ *
106
+ * `target_url` remains required for default `url` qURLs. It is optional in the
107
+ * type so callers can create non-url resource types such as tunnels without a
108
+ * URL; the client still throws a `ValidationError` when a url qURL omits it.
109
+ *
110
+ * `tags` and `description` are not accepted on this create path. They live on
111
+ * the resource and must be set through {@link UpdateInput} after creation.
112
+ */
113
+ export interface CreateInput {
114
+ type?: ResourceType;
115
+ target_url?: string;
116
+ expires_in?: string;
117
+ one_time_use?: boolean;
118
+ max_sessions?: number;
119
+ session_duration?: string;
120
+ label?: string;
121
+ access_policy?: AccessPolicy;
122
+ custom_domain?: string;
123
+ }
124
+ /** Response from creating a qURL. */
125
+ export interface CreateOutput {
126
+ qurl_id: string;
127
+ resource_id: string;
128
+ qurl_link: string;
129
+ branded_domain?: string;
130
+ qurl_site: string;
131
+ expires_at?: string;
132
+ label?: string;
133
+ type?: ResourceType;
134
+ }
135
+ /** Input for listing qURLs. */
136
+ export interface ListInput {
137
+ limit?: number;
138
+ cursor?: string;
139
+ status?: "active" | "revoked" | (string & {});
140
+ /** Free-text search over description and target_url. */
141
+ q?: string;
142
+ /** Sort field and direction as `field:direction`, for example `created_at:desc`. */
143
+ sort?: string;
144
+ /** RFC 3339 timestamp. */
145
+ created_after?: string;
146
+ /** RFC 3339 timestamp. */
147
+ created_before?: string;
148
+ /** RFC 3339 timestamp. */
149
+ expires_before?: string;
150
+ /** RFC 3339 timestamp. */
151
+ expires_after?: string;
152
+ }
153
+ /** Response from listing qURLs. */
154
+ export interface ListOutput extends PaginatedOutput {
155
+ qurls: QURL[];
156
+ }
157
+ /**
158
+ * Input for extending a qURL's expiration. Exactly one of `extend_by` or
159
+ * `expires_at` must be provided. The union moves the "provide at least one"
160
+ * and "do not provide both" checks into TypeScript for typed callers.
161
+ *
162
+ * ```ts
163
+ * client.extend("r_x", { extend_by: "7d" });
164
+ * client.extend("r_x", { expires_at: "2026-06-06T00:00:00Z" });
165
+ * client.extend("r_x", {}); // compile error
166
+ * client.extend("r_x", { extend_by: "7d", expires_at: "..." }); // compile error
167
+ * ```
168
+ */
169
+ export type ExtendInput = {
170
+ /** Relative duration to extend by (e.g., `"24h"`, `"7d"`). */
171
+ extend_by: string;
172
+ expires_at?: never;
173
+ } | {
174
+ /** Absolute RFC 3339 expiration timestamp. */
175
+ expires_at: string;
176
+ extend_by?: never;
177
+ };
178
+ /**
179
+ * Input for updating a qURL resource.
180
+ *
181
+ * `access_policy` is intentionally absent: token access policy is immutable on
182
+ * the resource-level update path and must be supplied at create/mint time or
183
+ * changed through the resource-scoped qURL-token endpoint.
184
+ */
185
+ export interface UpdateInput {
186
+ /** Relative duration to extend by (e.g., `"24h"`, `"7d"`). */
187
+ extend_by?: string;
188
+ /** Absolute RFC 3339 expiration timestamp. */
189
+ expires_at?: string;
190
+ /** Resource-level description. Pass an empty string to clear. */
191
+ description?: string;
192
+ /** Replace all tags on this resource. Pass an empty array to clear all tags. */
193
+ tags?: string[];
194
+ }
195
+ /**
196
+ * Input for minting an access link.
197
+ *
198
+ * `expires_in` and `expires_at` are mutually exclusive. If neither is set, the
199
+ * server applies its default expiration.
200
+ *
201
+ * This is intentionally not an {@link ExtendInput}-style union: minting allows
202
+ * zero or one expiration field, while extending requires exactly one. A
203
+ * three-arm union would make the common "omit both" case noisier than the
204
+ * runtime mutual-exclusion check is worth.
205
+ */
206
+ export interface MintInput {
207
+ /** Relative duration until expiration (e.g., `"5m"`, `"24h"`, `"7d"`). */
208
+ expires_in?: string;
209
+ /** Absolute RFC 3339 expiration timestamp. */
210
+ expires_at?: string;
211
+ /** Human-readable label identifying who this link is for. Max 500 chars. */
212
+ label?: string;
213
+ one_time_use?: boolean;
214
+ /** Maximum concurrent sessions. `0` = unlimited (default); max `1000`. */
215
+ max_sessions?: number;
216
+ /**
217
+ * How long access lasts after the page loads (e.g., `"1h"`). Min 1s, max
218
+ * 24h. The first create for a `target_url` anchors the resource-level cap;
219
+ * later mints/updates that exceed it are rejected by the server.
220
+ */
221
+ session_duration?: string;
222
+ access_policy?: AccessPolicy;
223
+ }
224
+ /** Response from minting an access link. */
225
+ export interface MintOutput {
226
+ qurl_id?: string;
227
+ qurl_link: string;
228
+ branded_domain?: string;
229
+ expires_at?: string;
230
+ type?: ResourceType;
231
+ }
232
+ /** Input for headless qURL resolution. */
233
+ export interface ResolveInput {
234
+ access_token: string;
235
+ }
236
+ /** Details of the network access that was granted. */
237
+ export interface AccessGrant {
238
+ expires_in: number;
239
+ granted_at: string;
240
+ src_ip: string;
241
+ }
242
+ /** Response from headless resolution. */
243
+ export interface ResolveOutput {
244
+ target_url: string;
245
+ resource_id: string;
246
+ access_grant?: AccessGrant;
247
+ }
248
+ /** Quota information. */
249
+ export interface Quota {
250
+ plan: "free" | "growth" | "enterprise" | (string & {});
251
+ period_start: string;
252
+ period_end: string;
253
+ /**
254
+ * The parent object and each inner limit are optional. Guard each field
255
+ * individually; partial responses and future tiers may expose only a subset.
256
+ */
257
+ rate_limits?: {
258
+ create_per_minute?: number;
259
+ create_per_hour?: number;
260
+ list_per_minute?: number;
261
+ resolve_per_minute?: number;
262
+ max_active_qurls?: number;
263
+ max_tokens_per_qurl?: number;
264
+ max_expiry_seconds?: number;
265
+ };
266
+ usage?: {
267
+ qurls_created?: number;
268
+ active_qurls?: number;
269
+ /**
270
+ * Active qURLs as a percentage of the plan's `max_active_qurls`, or `null`
271
+ * when the plan is unlimited. Guard the null case before arithmetic:
272
+ * `usage.active_qurls_percent * 0.01` yields `NaN` on unlimited plans.
273
+ */
274
+ active_qurls_percent?: number | null;
275
+ total_accesses?: number;
276
+ };
277
+ }
278
+ /** Input for batch creating qURLs. */
279
+ export interface BatchCreateInput {
280
+ /** Max 100 items per request; min 1. */
281
+ items: CreateInput[];
282
+ }
283
+ /**
284
+ * A successfully created item in a batch create response.
285
+ *
286
+ * This shape is intentionally slimmer than {@link CreateOutput}: batch items do
287
+ * not include `qurl_id` or `label`. Use the returned `resource_id` to fetch more
288
+ * detail when per-token identifiers are needed.
289
+ */
290
+ export interface BatchItemSuccess {
291
+ index: number;
292
+ success: true;
293
+ resource_id: string;
294
+ qurl_link: string;
295
+ branded_domain?: string;
296
+ qurl_site: string;
297
+ expires_at?: string;
298
+ }
299
+ /** A failed item in a batch create response. */
300
+ export interface BatchItemFailure {
301
+ index: number;
302
+ success: false;
303
+ error: {
304
+ code: string;
305
+ message: string;
306
+ };
307
+ }
308
+ /** Result for a single item in a batch create response. */
309
+ export type BatchItemResult = BatchItemSuccess | BatchItemFailure;
310
+ /** Response from batch creating qURLs. */
311
+ export interface BatchCreateOutput {
312
+ succeeded: number;
313
+ failed: number;
314
+ results: BatchItemResult[];
315
+ request_id?: string;
316
+ }
317
+ /** Input for creating a resource directly. */
318
+ export interface CreateResourceInput {
319
+ type?: ResourceType;
320
+ target_url?: string;
321
+ description?: string;
322
+ tags?: string[];
323
+ custom_domain?: string;
324
+ alias?: string;
325
+ slug?: string;
326
+ find_or_create?: boolean;
327
+ }
328
+ /** Input for updating resource metadata. */
329
+ export interface UpdateResourceInput {
330
+ description?: string;
331
+ tags?: string[];
332
+ /** Omit to leave unchanged; send `""` to clear. `null` is not a clear signal. */
333
+ custom_domain?: string;
334
+ preserve_host?: boolean;
335
+ /** Use `null` to clear the alias. */
336
+ alias?: string | null;
337
+ }
338
+ /** Resource data returned by the `/v1/resources` surface. */
339
+ export interface Resource {
340
+ resource_id: string;
341
+ type?: ResourceType;
342
+ target_url?: string;
343
+ knock_resource_id?: string;
344
+ status?: "active" | "revoked" | (string & {});
345
+ description?: string;
346
+ tags?: string[];
347
+ custom_domain?: string | null;
348
+ alias?: string | null;
349
+ slug?: string;
350
+ preserve_host?: boolean;
351
+ session_duration_cap?: number;
352
+ qurl_count?: number;
353
+ created_at?: string;
354
+ expires_at?: string;
355
+ tombstoned_at?: string;
356
+ }
357
+ /** Detail payload for one resource plus its bounded qURL preview. */
358
+ export interface ResourceDetail {
359
+ resource?: Resource;
360
+ qurls?: QurlSummary[];
361
+ }
362
+ export interface ResourceListInput {
363
+ cursor?: string;
364
+ limit?: number;
365
+ alias?: string;
366
+ slug?: string;
367
+ status?: "active" | "revoked" | (string & {});
368
+ type?: ResourceType;
369
+ }
370
+ export interface ResourceListOutput extends PaginatedOutput {
371
+ resources: Resource[];
372
+ }
373
+ /** Input for minting a qURL against an existing resource. */
374
+ export type CreateQurlForResourceInput = Omit<CreateInput, "target_url" | "custom_domain" | "type">;
375
+ type UpdateResourceQurlBaseInput = {
376
+ label?: string;
377
+ access_policy?: AccessPolicy;
378
+ max_sessions?: number;
379
+ session_duration?: string;
380
+ };
381
+ /**
382
+ * Input for updating a specific qURL token on a resource.
383
+ *
384
+ * `extend_by` and `expires_at` are mutually exclusive. Callers may omit both
385
+ * when only updating non-expiration token fields such as `label`,
386
+ * `max_sessions`, `session_duration`, or `access_policy`.
387
+ */
388
+ export type UpdateResourceQurlInput = (UpdateResourceQurlBaseInput & {
389
+ extend_by?: string;
390
+ expires_at?: never;
391
+ }) | (UpdateResourceQurlBaseInput & {
392
+ expires_at?: string;
393
+ extend_by?: never;
394
+ });
395
+ export interface Session {
396
+ session_id?: string;
397
+ qurl_id?: string;
398
+ src_ip?: string;
399
+ user_agent?: string;
400
+ created_at?: string;
401
+ last_seen_at?: string;
402
+ }
403
+ /** Metadata surfaced by list endpoints that are not paginated today. */
404
+ export interface UnpaginatedOutput {
405
+ request_id?: string;
406
+ /**
407
+ * These endpoints do not accept cursor query params today; pagination drift
408
+ * is surfaced through debug logs, not through a pageable output contract.
409
+ */
410
+ has_more: false;
411
+ page_size?: number;
412
+ }
413
+ export interface SessionListOutput extends UnpaginatedOutput {
414
+ /**
415
+ * Active sessions. The current OpenAPI contract has no cursor query params;
416
+ * if pagination metadata appears, the SDK surfaces it for observability but
417
+ * returns this page only.
418
+ */
419
+ sessions: Session[];
420
+ }
421
+ export interface SessionTerminateOutput {
422
+ terminated: number;
423
+ request_id?: string;
424
+ }
425
+ export interface ConnectorInstallationStats {
426
+ resources: number;
427
+ qurls: number;
428
+ accesses_24h: number;
429
+ accesses_7d: number;
430
+ errors_24h: number;
431
+ }
432
+ export interface ConnectorInstallationCapabilities {
433
+ configure: boolean;
434
+ disconnect: boolean;
435
+ reauth: boolean;
436
+ view_activity: boolean;
437
+ }
438
+ export interface ConnectorInstallation {
439
+ installation_id: string;
440
+ plugin_id: string;
441
+ label: string;
442
+ subject_kind: string;
443
+ subject_display_name: string;
444
+ status: OpenString<"active" | "degraded" | "disconnected" | "needs_reauth">;
445
+ installed_at: string;
446
+ last_activity_at?: string | null;
447
+ stats: ConnectorInstallationStats;
448
+ capabilities: ConnectorInstallationCapabilities;
449
+ }
450
+ export interface ListConnectorInstallationsInput {
451
+ cursor?: string;
452
+ limit?: number;
453
+ }
454
+ export interface ConnectorInstallationListOutput extends PaginatedOutput {
455
+ installations: ConnectorInstallation[];
456
+ }
457
+ export interface UsageCostEstimate {
458
+ currency: string;
459
+ amount_cents: number;
460
+ description: string;
461
+ }
462
+ export interface UsageCurrentPeriod {
463
+ tier: "free" | "growth" | "enterprise" | (string & {});
464
+ period_start: string;
465
+ period_end: string;
466
+ qurls_created: number;
467
+ active_qurls: number;
468
+ cost_estimate?: UsageCostEstimate;
469
+ }
470
+ export interface UsageDailyEntry {
471
+ date: string;
472
+ qurls_created: number;
473
+ }
474
+ export interface UsageDaily {
475
+ tier: "free" | "growth" | "enterprise" | (string & {});
476
+ period_start: string;
477
+ period_end: string;
478
+ daily: UsageDailyEntry[];
479
+ }
480
+ export interface Customer {
481
+ tier: "free" | "growth" | "enterprise" | (string & {});
482
+ spending_cap_cents: number;
483
+ current_period_usage: number;
484
+ frozen: boolean;
485
+ frozen_reason?: OpenString<"spending_cap" | "payment_failed" | "manual"> | null;
486
+ }
487
+ export interface UpdateCustomerInput {
488
+ /** Non-negative spending cap in cents. Clearing/removal is not exposed by the current contract. */
489
+ spending_cap_cents: number;
490
+ }
491
+ export interface CreateBillingCheckoutInput {
492
+ plan: OpenString<"growth">;
493
+ }
494
+ export interface CheckoutSession {
495
+ url: string;
496
+ }
497
+ export interface PortalSession {
498
+ url: string;
499
+ }
500
+ export interface Invoice {
501
+ id: string;
502
+ amount_cents: number;
503
+ status: "paid" | "open" | "void" | "draft" | (string & {});
504
+ created_at: string;
505
+ pdf_url?: string | null;
506
+ }
507
+ export interface ListBillingInvoicesInput {
508
+ limit?: number;
509
+ cursor?: string;
510
+ }
511
+ export interface BillingInvoiceListOutput extends PaginatedOutput {
512
+ invoices: Invoice[];
513
+ }
514
+ export interface RegisterDomainInput {
515
+ domain: string;
516
+ }
517
+ export interface DnsRecord {
518
+ type?: string;
519
+ name?: string;
520
+ value?: string;
521
+ verified?: boolean;
522
+ }
523
+ export interface Domain {
524
+ domain?: string;
525
+ status?: OpenString<"pending_verification" | "verified" | "provisioning_tls" | "active" | "failed">;
526
+ verification_token?: string;
527
+ token_expires_at?: string | null;
528
+ acme_cname_target?: string;
529
+ created_at?: string;
530
+ verified_at?: string | null;
531
+ activated_at?: string | null;
532
+ ready_for_qurls?: boolean;
533
+ dns_records?: DnsRecord[];
534
+ }
535
+ export interface ListDomainsInput {
536
+ limit?: number;
537
+ cursor?: string;
538
+ }
539
+ export interface DomainListOutput extends PaginatedOutput {
540
+ domains: Domain[];
541
+ }
542
+ export interface DomainCheckDetail {
543
+ verified: boolean;
544
+ error?: string;
545
+ found?: string;
546
+ }
547
+ export interface DomainVerifyResult {
548
+ domain?: string;
549
+ status?: Domain["status"];
550
+ checks?: {
551
+ txt?: DomainCheckDetail;
552
+ acme_cname?: DomainCheckDetail;
553
+ traffic_routing?: DomainCheckDetail;
554
+ };
555
+ }
556
+ export type WebhookEventType = OpenString<"qurl.created" | "qurl.expired" | "qurl.revoked" | "qurl.updated" | "resource.closed" | "qurl.accessed" | "qurl.access_denied" | "qurl.token_exhausted" | "quota.warning" | "quota.exceeded" | "token.minted" | "token.expired" | "domain.verified" | "domain.failed" | "domain.deleted">;
557
+ export interface CreateWebhookInput {
558
+ /** Webhook receiver URL. The service accepts public http/https URLs; prefer https in production. */
559
+ url: string;
560
+ events: WebhookEventType[];
561
+ description?: string;
562
+ }
563
+ export interface UpdateWebhookInput {
564
+ url?: string;
565
+ events?: WebhookEventType[];
566
+ description?: string;
567
+ status?: "active" | "disabled" | (string & {});
568
+ }
569
+ export interface Webhook {
570
+ webhook_id?: string;
571
+ owner_id?: string;
572
+ url?: string;
573
+ events?: WebhookEventType[];
574
+ status?: "active" | "disabled" | (string & {});
575
+ description?: string;
576
+ created_at?: string;
577
+ updated_at?: string;
578
+ failure_count?: number;
579
+ last_delivery_success?: boolean;
580
+ last_delivery_time?: number;
581
+ }
582
+ export interface WebhookWithSecret extends Webhook {
583
+ secret?: string;
584
+ }
585
+ export interface ListWebhooksInput {
586
+ limit?: number;
587
+ cursor?: string;
588
+ }
589
+ export interface WebhookListOutput extends PaginatedOutput {
590
+ webhooks: Webhook[];
591
+ }
592
+ export interface WebhookDelivery {
593
+ delivery_id?: string;
594
+ webhook_id?: string;
595
+ event_type?: WebhookEventType;
596
+ status?: "pending" | "success" | "failed" | "retrying" | "abandoned" | (string & {});
597
+ response_code?: number;
598
+ response_body?: string;
599
+ error_message?: string;
600
+ duration_ms?: number;
601
+ retry_count?: number;
602
+ created_at?: string;
603
+ completed_at?: string;
604
+ }
605
+ export interface ListWebhookDeliveriesInput {
606
+ limit?: number;
607
+ cursor?: string;
608
+ }
609
+ export interface WebhookDeliveryListOutput extends PaginatedOutput {
610
+ deliveries: WebhookDelivery[];
611
+ }
612
+ export interface WebhookEventTypeInfo {
613
+ type?: WebhookEventType;
614
+ category?: "resource" | "access" | "quota" | "token" | (string & {});
615
+ description?: string;
616
+ }
617
+ export interface WebhookPayload {
618
+ id?: string;
619
+ type?: WebhookEventType;
620
+ owner_id?: string;
621
+ timestamp?: string;
622
+ api_version?: string;
623
+ data?: Record<string, unknown>;
624
+ }
625
+ export type ApiKeyScope = OpenString<"qurl:read" | "qurl:write" | "qurl:resolve" | "qurl:agent">;
626
+ export interface CreateApiKeyInput {
627
+ name: string;
628
+ scopes: ApiKeyScope[];
629
+ expires_in?: string;
630
+ purpose?: "tunnel_bootstrap";
631
+ tunnel_slug?: string;
632
+ }
633
+ export interface UpdateApiKeyInput {
634
+ name?: string;
635
+ scopes?: ApiKeyScope[];
636
+ }
637
+ export interface ApiKey {
638
+ key_id?: string;
639
+ key_prefix?: string;
640
+ name?: string;
641
+ scopes?: ApiKeyScope[];
642
+ status?: "active" | "revoked" | (string & {});
643
+ created_at?: string;
644
+ updated_at?: string;
645
+ last_used_at?: string;
646
+ expires_at?: string;
647
+ purpose?: "tunnel_bootstrap" | (string & {});
648
+ tunnel_slug?: string;
649
+ }
650
+ export interface CreateApiKeyOutput extends ApiKey {
651
+ /** Full API key secret, returned only on create. Store it immediately. */
652
+ api_key?: string;
653
+ }
654
+ export interface ListApiKeysInput {
655
+ limit?: number;
656
+ cursor?: string;
657
+ status?: "active" | "revoked" | (string & {});
658
+ }
659
+ export interface ApiKeyListOutput extends PaginatedOutput {
660
+ api_keys: ApiKey[];
661
+ }
662
+ export interface RedeemAccessCodeInput {
663
+ code: string;
664
+ honeypot?: string;
665
+ elapsed_ms?: number;
666
+ }
667
+ export interface RedeemAccessCodeOutput {
668
+ redirect_url?: string;
669
+ }
670
+ export interface CreateAccessCodeInput {
671
+ resource_id: string;
672
+ name?: string;
673
+ max_uses?: number;
674
+ expires_at?: string;
675
+ }
676
+ export interface AccessCode {
677
+ access_code_id?: string;
678
+ resource_id?: string;
679
+ name?: string;
680
+ status?: "active" | "revoked" | (string & {});
681
+ max_uses?: number;
682
+ use_count?: number;
683
+ created_at?: string;
684
+ expires_at?: string | null;
685
+ }
686
+ export interface CreateAccessCodeOutput extends AccessCode {
687
+ /** Full access code secret, returned only on create. Store it immediately. */
688
+ code?: string;
689
+ }
690
+ export interface AccessCodeListOutput extends UnpaginatedOutput {
691
+ /**
692
+ * Access codes. The current OpenAPI contract has no cursor query params; if
693
+ * pagination metadata appears, the SDK surfaces it for observability but
694
+ * returns this page only.
695
+ */
696
+ access_codes: AccessCode[];
697
+ }
698
+ export interface AgentBootstrapInput {
699
+ public_key: string;
700
+ agent_id?: string;
701
+ hostname?: string;
702
+ version?: string;
703
+ }
704
+ export interface NHPServerPeerInfo {
705
+ public_key_b64: string;
706
+ host: string;
707
+ port: number;
708
+ expire_time: number;
709
+ }
710
+ export interface AgentBootstrapOutput {
711
+ agent_id: string;
712
+ registered_at: string;
713
+ nhp_server_peer: NHPServerPeerInfo;
714
+ }
715
+ /** API error from the qURL service (RFC 7807). */
716
+ export interface QURLErrorData {
717
+ status: number;
718
+ code: string;
719
+ title: string;
720
+ /** Human-readable explanation. Optional per RFC 7807. */
721
+ detail?: string;
722
+ /** Problem-type URI (RFC 7807 `type`). Optional. */
723
+ type?: string;
724
+ /** URI reference that identifies the specific occurrence (RFC 7807 `instance`). Optional. */
725
+ instance?: string;
726
+ invalid_fields?: Record<string, string>;
727
+ request_id?: string;
728
+ retry_after?: number;
729
+ }
730
+ /** Per-call options accepted by mutating requests. */
731
+ export interface RequestOptions {
732
+ /**
733
+ * Override the auto-generated `Idempotency-Key` sent on POST/PATCH.
734
+ *
735
+ * Use this when an upstream operation already has a stable request ID
736
+ * and application-level retry loops should deduplicate against that ID
737
+ * instead of a fresh SDK-created UUIDv7. Values must be non-empty printable
738
+ * ASCII strings of at most 256 characters and must not start or end with
739
+ * spaces. Use a unique key for each logical operation.
740
+ */
741
+ idempotencyKey?: string;
742
+ }
743
+ /** Client configuration options. */
744
+ export interface ClientOptions {
745
+ /** API key (required). */
746
+ apiKey: string;
747
+ /** Base URL. Defaults to https://api.layerv.ai */
748
+ baseUrl?: string;
749
+ /** Custom fetch implementation. */
750
+ fetch?: typeof globalThis.fetch;
751
+ /** Maximum retry attempts for transient errors (429, 5xx). Default: 3. */
752
+ maxRetries?: number;
753
+ /**
754
+ * Request timeout in milliseconds, per attempt (not total). Default: 30000.
755
+ *
756
+ * Worst-case total time for a request that exhausts all retries is roughly
757
+ * `timeout * (maxRetries + 1) + sum(retryDelay)`.
758
+ */
759
+ timeout?: number;
760
+ /** User-Agent header value. */
761
+ userAgent?: string;
762
+ /** Enable debug logging. Pass `true` for console.debug, or a custom callback. */
763
+ debug?: boolean | ((message: string, data?: Record<string, unknown>) => void);
764
+ }
765
+ export {};