@layervai/qurl 0.7.0 → 2.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.
Files changed (121) hide show
  1. package/README.md +212 -1
  2. package/dist/cjs/client.d.ts +19 -1
  3. package/dist/cjs/client.js +520 -9
  4. package/dist/cjs/crid.d.ts +2 -1
  5. package/dist/cjs/crid.js +11 -2
  6. package/dist/cjs/errors.d.ts +20 -3
  7. package/dist/cjs/errors.js +31 -4
  8. package/dist/cjs/index.d.ts +2 -2
  9. package/dist/cjs/index.js +3 -1
  10. package/dist/cjs/node/agent-runtime.d.ts +108 -0
  11. package/dist/cjs/node/agent-runtime.js +952 -0
  12. package/dist/cjs/node/agent-state.d.ts +100 -0
  13. package/dist/cjs/node/agent-state.js +311 -0
  14. package/dist/cjs/node/agent-transport.d.ts +17 -0
  15. package/dist/cjs/node/agent-transport.js +118 -0
  16. package/dist/cjs/node/deployment.d.ts +6 -0
  17. package/dist/cjs/node/deployment.js +24 -3
  18. package/dist/cjs/node/file-agent-state.d.ts +15 -0
  19. package/dist/cjs/node/file-agent-state.js +137 -0
  20. package/dist/cjs/node/native-loader.cjs +7 -0
  21. package/dist/cjs/node/native-loader.d.cts +11 -0
  22. package/dist/cjs/node/native-udp.d.ts +8 -3
  23. package/dist/cjs/node/native-udp.js +8 -3
  24. package/dist/cjs/node/nhp-wire.d.ts +9 -0
  25. package/dist/cjs/node/nhp-wire.js +24 -7
  26. package/dist/cjs/node/portal-opener.d.ts +7 -0
  27. package/dist/cjs/node/portal-opener.js +28 -6
  28. package/dist/cjs/node/provider.d.ts +19 -0
  29. package/dist/cjs/node/provider.js +153 -0
  30. package/dist/cjs/node/qv2.d.ts +3 -1
  31. package/dist/cjs/node/qv2.js +16 -2
  32. package/dist/cjs/node/relay.d.ts +12 -0
  33. package/dist/cjs/node/relay.js +111 -0
  34. package/dist/cjs/node/sealed-agent-state.d.ts +19 -0
  35. package/dist/cjs/node/sealed-agent-state.js +193 -0
  36. package/dist/cjs/node/strict-json.d.ts +1 -1
  37. package/dist/cjs/node/strict-json.js +8 -3
  38. package/dist/cjs/node.d.ts +14 -0
  39. package/dist/cjs/node.js +24 -1
  40. package/dist/cjs/types.d.ts +97 -0
  41. package/dist/cjs/version.d.ts +1 -1
  42. package/dist/cjs/version.js +1 -1
  43. package/dist/esm/client.d.ts +19 -1
  44. package/dist/esm/client.d.ts.map +1 -1
  45. package/dist/esm/client.js +521 -10
  46. package/dist/esm/client.js.map +1 -1
  47. package/dist/esm/crid.d.ts +2 -1
  48. package/dist/esm/crid.d.ts.map +1 -1
  49. package/dist/esm/crid.js +10 -2
  50. package/dist/esm/crid.js.map +1 -1
  51. package/dist/esm/errors.d.ts +20 -3
  52. package/dist/esm/errors.d.ts.map +1 -1
  53. package/dist/esm/errors.js +29 -3
  54. package/dist/esm/errors.js.map +1 -1
  55. package/dist/esm/index.d.ts +2 -2
  56. package/dist/esm/index.d.ts.map +1 -1
  57. package/dist/esm/index.js +1 -1
  58. package/dist/esm/index.js.map +1 -1
  59. package/dist/esm/node/agent-runtime.d.ts +109 -0
  60. package/dist/esm/node/agent-runtime.d.ts.map +1 -0
  61. package/dist/esm/node/agent-runtime.js +946 -0
  62. package/dist/esm/node/agent-runtime.js.map +1 -0
  63. package/dist/esm/node/agent-state.d.ts +101 -0
  64. package/dist/esm/node/agent-state.d.ts.map +1 -0
  65. package/dist/esm/node/agent-state.js +298 -0
  66. package/dist/esm/node/agent-state.js.map +1 -0
  67. package/dist/esm/node/agent-transport.d.ts +18 -0
  68. package/dist/esm/node/agent-transport.d.ts.map +1 -0
  69. package/dist/esm/node/agent-transport.js +114 -0
  70. package/dist/esm/node/agent-transport.js.map +1 -0
  71. package/dist/esm/node/deployment.d.ts +6 -0
  72. package/dist/esm/node/deployment.d.ts.map +1 -1
  73. package/dist/esm/node/deployment.js +23 -3
  74. package/dist/esm/node/deployment.js.map +1 -1
  75. package/dist/esm/node/file-agent-state.d.ts +16 -0
  76. package/dist/esm/node/file-agent-state.d.ts.map +1 -0
  77. package/dist/esm/node/file-agent-state.js +134 -0
  78. package/dist/esm/node/file-agent-state.js.map +1 -0
  79. package/dist/esm/node/native-loader.cjs +7 -0
  80. package/dist/esm/node/native-loader.d.cts +11 -0
  81. package/dist/esm/node/native-udp.d.ts +8 -3
  82. package/dist/esm/node/native-udp.d.ts.map +1 -1
  83. package/dist/esm/node/native-udp.js +7 -5
  84. package/dist/esm/node/native-udp.js.map +1 -1
  85. package/dist/esm/node/nhp-wire.d.ts +9 -0
  86. package/dist/esm/node/nhp-wire.d.ts.map +1 -1
  87. package/dist/esm/node/nhp-wire.js +23 -6
  88. package/dist/esm/node/nhp-wire.js.map +1 -1
  89. package/dist/esm/node/portal-opener.d.ts +7 -0
  90. package/dist/esm/node/portal-opener.d.ts.map +1 -1
  91. package/dist/esm/node/portal-opener.js +28 -6
  92. package/dist/esm/node/portal-opener.js.map +1 -1
  93. package/dist/esm/node/provider.d.ts +20 -0
  94. package/dist/esm/node/provider.d.ts.map +1 -0
  95. package/dist/esm/node/provider.js +149 -0
  96. package/dist/esm/node/provider.js.map +1 -0
  97. package/dist/esm/node/qv2.d.ts +3 -1
  98. package/dist/esm/node/qv2.d.ts.map +1 -1
  99. package/dist/esm/node/qv2.js +17 -3
  100. package/dist/esm/node/qv2.js.map +1 -1
  101. package/dist/esm/node/relay.d.ts +13 -0
  102. package/dist/esm/node/relay.d.ts.map +1 -0
  103. package/dist/esm/node/relay.js +105 -0
  104. package/dist/esm/node/relay.js.map +1 -0
  105. package/dist/esm/node/sealed-agent-state.d.ts +20 -0
  106. package/dist/esm/node/sealed-agent-state.d.ts.map +1 -0
  107. package/dist/esm/node/sealed-agent-state.js +190 -0
  108. package/dist/esm/node/sealed-agent-state.js.map +1 -0
  109. package/dist/esm/node/strict-json.d.ts +1 -1
  110. package/dist/esm/node/strict-json.d.ts.map +1 -1
  111. package/dist/esm/node/strict-json.js +8 -3
  112. package/dist/esm/node/strict-json.js.map +1 -1
  113. package/dist/esm/node.d.ts +14 -0
  114. package/dist/esm/node.d.ts.map +1 -1
  115. package/dist/esm/node.js +7 -0
  116. package/dist/esm/node.js.map +1 -1
  117. package/dist/esm/types.d.ts +97 -0
  118. package/dist/esm/types.d.ts.map +1 -1
  119. package/dist/esm/version.d.ts +1 -1
  120. package/dist/esm/version.js +1 -1
  121. package/package.json +16 -7
package/README.md CHANGED
@@ -182,7 +182,16 @@ console.log(share.qurlId); // Safe handle for revoking only this link later
182
182
  `shareResource` returns the current share-safe `#qv2t1...` link. Recipients
183
183
  open that URL in the qURL browser flow. For native TypeScript opening, pass
184
184
  `share.link` to `createPortalOpener` from `@layervai/qurl/node` with trusted
185
- `QURL_DEPLOYMENT` configuration. See the native opener example above.
185
+ `QURL_DEPLOYMENT` configuration and `expectedCRID: advertisedCRID`.
186
+ Obtain `advertisedCRID` independently of the response carrying the link.
187
+ The opener verifies the issuer signature and CRID/key binding before each
188
+ native access request, including renewals. Empty, malformed, unsupported,
189
+ and mismatched CRIDs fail closed. Omitting the option retains link-only access.
190
+ This verifies resource identity, not content or current revocation state.
191
+ The access-binding check accepts only locally registered versions and their
192
+ registered digest widths, matching the Go SDK and browser agent. Upgrade the
193
+ SDK when a new version is activated. This is stricter than the forwarding
194
+ and supplied-key helper below. See the native opener example below.
186
195
  `verifyCrid` does not open the link or make a network request.
187
196
 
188
197
  `verifyCrid` verifies that the response CRID derives from the trusted resource
@@ -259,6 +268,74 @@ await client.updateApiKey(keyId, { scopes });
259
268
  This credential surface requires the kind-first qurl-service contract at or
260
269
  after commit `047cf31e1cdf545e3060e0f9294d738a19fb997b`.
261
270
 
271
+ ## Delegated qURL batches
272
+
273
+ Services with a delegated mint capability can create up to 100 ordered grants
274
+ without an API call per recipient:
275
+
276
+ ```typescript
277
+ import { DelegatedBatchOutcomeUnknownError, QURLClient } from '@layervai/qurl';
278
+
279
+ const client = new QURLClient({ apiKey: process.env.QURL_API_KEY! });
280
+ const key = crypto.randomUUID();
281
+ const mintCapability = process.env.QURL_MINT_CAPABILITY!;
282
+ const recipients = [{ name: 'Alice' }];
283
+
284
+ const accepted = await client
285
+ .createDelegatedQurlBatch(
286
+ {
287
+ mint_capability: mintCapability,
288
+ grants: recipients.map((recipient) => ({ label: recipient.name, expires_in: '1h' })),
289
+ },
290
+ { idempotencyKey: key },
291
+ )
292
+ .catch((error: unknown) => {
293
+ if (error instanceof DelegatedBatchOutcomeUnknownError && error.batchId) {
294
+ console.error('Poll the accepted batch before retrying', { batchId: error.batchId });
295
+ }
296
+ // A deliberate retry must reuse this key and exact body.
297
+ throw error;
298
+ });
299
+
300
+ let etag = accepted.etag;
301
+ let retryAfter = accepted.retry_after;
302
+ let state;
303
+ const deadline = Date.now() + 60_000;
304
+ for (let polls = 0; polls < 30 && Date.now() < deadline; polls++) {
305
+ await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
306
+ state = await client.getDelegatedQurlBatch(accepted.batch_id, { etag });
307
+ if (state.http_status === 304) {
308
+ retryAfter = state.retry_after ?? retryAfter;
309
+ } else if (state.http_status === 202) {
310
+ ({ etag, retry_after: retryAfter } = state);
311
+ } else {
312
+ break;
313
+ }
314
+ }
315
+
316
+ if (state?.http_status !== 200) throw new Error('Delegated qURL batch did not finish');
317
+
318
+ if (state.results[0]?.status === 'succeeded') {
319
+ const qurlId = state.results[0].qurl.qurl_id;
320
+ const metadata = await client.getDelegatedQurl(qurlId);
321
+ console.log(metadata.status);
322
+ await client.deleteDelegatedQurl(qurlId);
323
+ }
324
+ ```
325
+
326
+ The idempotency key must contain 32–256 visible ASCII characters. A UUID meets
327
+ this requirement.
328
+
329
+ One read makes one HTTP attempt. The caller owns the poll count, total deadline,
330
+ and wait from `retry_after`. A `304` means the prior ETag is still current. A
331
+ `200` contains the terminal, input-ordered results. Keep each returned qURL as
332
+ an opaque bearer link and apply any deployment-specific origin check before
333
+ publishing it.
334
+
335
+ Delegated DELETE calls are not retried automatically. After a transport failure
336
+ or `503 mutation_outcome_unknown`, retry the same qURL ID until the service
337
+ returns `204`.
338
+
262
339
  ## Opening Portals
263
340
 
264
341
  Most recipients open qURL links directly and do not use this SDK at all. If
@@ -298,6 +375,7 @@ const { createPortalOpener } = require('@layervai/qurl/node');
298
375
  async function uploadPrivateObject(uploadBody) {
299
376
  const opener = createPortalOpener({
300
377
  qurl: process.env.PRIVATE_UPLOAD_QURL,
378
+ expectedCRID: process.env.PRIVATE_UPLOAD_CRID ?? '', // Independently held; missing fails closed.
301
379
  });
302
380
  try {
303
381
  await opener.start();
@@ -585,6 +663,7 @@ try {
585
663
  | `ServerError` | 5xx | Server-side failure |
586
664
  | `NetworkError` | — | Connection failure |
587
665
  | `TimeoutError` | — | Request exceeded timeout |
666
+ | `DelegatedBatchOutcomeUnknownError` | — | Dispatched batch create needs reconciliation |
588
667
 
589
668
  Client-detected failures use `status: 0` with a discriminating `code`:
590
669
  `"client_validation"` for bad input caught before a request, and — on the
@@ -757,3 +836,135 @@ MIT
757
836
  Resource verification requires Web Crypto (`crypto.subtle`). In browsers, use
758
837
  an HTTPS page or localhost. Raw REST response types keep `crid` optional;
759
838
  resource handles and portals require a validated CRID.
839
+
840
+ ## Node producer runtime (SDK 2.x, NHP 1.1)
841
+
842
+ The SDK implements the producer lifecycle in TypeScript. A small optional native
843
+ package, `@layervai/qurl-state-fs`, supplies descriptor-relative filesystem
844
+ operations on Linux and macOS. There is no bundled Go runtime. The portable
845
+ `@layervai/qurl` entry point does not load the native module.
846
+
847
+ ```ts
848
+ import { FileAgentState, connectAgentRuntime } from '@layervai/qurl/node';
849
+
850
+ const store = new FileAgentState('/private/agent/state.json');
851
+ const runtime = await connectAgentRuntime(store, {
852
+ hub: { host: 'hub.nhp.layerv.ai', port: 443, server_public_key_b64: hubPublicKey },
853
+ headless: true,
854
+ enrollmentCredential: bootstrapCredential,
855
+ });
856
+ try {
857
+ // runtime.client uses the durable device credential, with bounded reloads.
858
+ const grant = await runtime.knock(knockResourceID, {
859
+ protectedResourceID: crid, runID: '0123456789abcdef', runAttempt: 1n,
860
+ });
861
+ // Keep the original receipt. It retains the issuing cell across relocation.
862
+ await runtime.retire(grant.receipt);
863
+ } finally {
864
+ await runtime.close();
865
+ store.close();
866
+ }
867
+ ```
868
+
869
+ A registered state opens without enrollment or network work while its assignment
870
+ lease is current. An explicit Hub option or the `hub` field in `QURL_DEPLOYMENT`
871
+ provides refresh trust. `runtime.refresh()` handles assignment renewal and
872
+ relocation. `knock()` attempts renewal near lease expiry and refuses expired
873
+ assignments. Account enrollment uses an explicit `otpProvider` instead of
874
+ `headless`. Resume an interrupted enrollment with the same credential and
875
+ metadata. The SDK persists activation and completion replay authority before
876
+ sending the corresponding mutation.
877
+
878
+ `recoverAgentRuntime(store, recoveryCredential, { hub })` starts explicit device
879
+ credential recovery. It persists the issue nonce, replacement candidate, and
880
+ recovery horizon. It saves the recovered credential before mandatory assignment
881
+ refresh. A failed refresh resumes without another recovery grant. No startup
882
+ path silently resets an existing identity.
883
+
884
+ Legacy pre-v6 pending-completion state remains readable, but enrollment returns
885
+ `RECOVERY_MIGRATION_REQUIRED` without UDP or state changes. Those records lack
886
+ an authenticated recovery deadline; explicit recovery or reprovisioning is required.
887
+ Filesystem state creation honors the process umask and creates missing ancestors.
888
+ Keep owner read/write/search permissions enabled (for example, umask `077`);
889
+ unsafe existing permissions or an incompatible umask fail closed.
890
+
891
+ `FileAgentState` uses a private directory, mode 0600 files, a process-safe setup
892
+ lock, exclusive temporary files, file and directory fsync, and atomic replacement.
893
+ It rejects symlinks, hard links, unsafe permissions, and directory or lock
894
+ replacement. Await `runtime.close()` before closing the store. Inside `withLock`,
895
+ use the supplied locked handle; using the outer store waits until the lock timeout.
896
+ Crash-abandoned `.qurl-*` temporary files remain private but need offline cleanup;
897
+ automatic sweeps could race other state files in the same directory. Filesystem state
898
+ uses synchronous native I/O, including fsync, on the event loop. Use local storage;
899
+ slow or network filesystems can block the process. Continuity checks also run before
900
+ lifecycle datagrams and cannot be cached safely across external directory changes.
901
+ An existing state directory must be owned by the process user with mode 0700.
902
+ On macOS, `/var`, `/tmp`, and `/etc` resolve through their standard `/private` paths.
903
+ A save error after rename can mean the new state is present but its durability is
904
+ unconfirmed; do not assume the previous state remains. Filesystem state
905
+ currently requires Linux or macOS; unsupported platforms fail closed. Install
906
+ scripts may be disabled when a matching prebuilt native binary is available.
907
+ Linux x64/arm64 prebuilds distinguish glibc and musl; CI tests Ubuntu 24.04 and
908
+ Alpine 3.22. macOS prebuilds cover x64 and arm64.
909
+
910
+ For sealed state, use `openSealedFileAgentState(path, providerID, keyWrapper,
911
+ expectedAgentID)`. Each save uses a fresh AES-256-GCM key and verifies wrapping and
912
+ unwrapping before commit. The envelope is compatible with the pinned Go SDK.
913
+ Sealing authenticates the agent, provider, purpose, version, and wrapped-key
914
+ metadata. It does not detect rollback to an older valid envelope. JavaScript
915
+ strings cannot be reliably erased; avoid logging state or credentials.
916
+
917
+ AWS adapters are separate exports from `@layervai/qurl-aws` (ESM and CommonJS).
918
+ Install the AWS client for the subpath you use: `/ssm`, `/secrets-manager`, or
919
+ `/kms`. These clients are optional peer dependencies. Importing the root barrel
920
+ requires all three clients.
921
+
922
+
923
+ - `createSSMAgentStateStore(ssmClient, parameterName, { kmsKeyID, tier })` stores
924
+ SecureString parameters and enforces tier size limits.
925
+ - `createSecretsManagerAgentStateStore(secretsClient, secretID, kmsKeyID)` handles
926
+ missing-secret creation races with one write token.
927
+ - `createKMSAgentStateKeyWrapper(kmsClient, keyID)` wraps only the data key and
928
+ authenticates all four state-binding fields in the KMS encryption context.
929
+
930
+ SSM and Secrets Manager stores serialize lifecycle calls within one store handle.
931
+ Loads outside a lifecycle lock can read the previous committed state.
932
+ They require one process to own each state object: these services do not provide
933
+ an agent setup transaction lock. KMS is a key wrapper, not a state store.
934
+
935
+ ## Explicit relay and discovery
936
+
937
+ Native UDP remains the default transport. An unknown native cell fails closed, including
938
+ when a relay allowlist exists. Select `transport: 'relay'` explicitly to use HTTPS
939
+ relay. Explicit relay trust uses signed qv2 claims and the relay allowlist, not
940
+ the native cell catalog. Relay URLs must match that deployment trust.
941
+ Redirects and oversized responses are refused. A hostname-only allowlist entry
942
+ authorizes all ports on that host; use `host:port` to limit the port.
943
+
944
+ `createStaticProvider(deployment)` snapshots fixed trust. For discovery, use
945
+ `createDiscoveryProvider({ fetcher, pinSHA256, manifestKeys, requireSignature,
946
+ minVersion, expectedProfile })` and `createHTTPManifestFetcher(httpsURL)`. Supply
947
+ a manifest pin or signing keys. Discovery is relay-only and requires
948
+ `transport: 'relay'`; native UDP requires a static cell catalog. Discovery verifies the domain-separated low-S
949
+ signature when configured, validity times, profile, and monotonic version floor.
950
+ It never returns stale trust after a failed refresh. Persist `minVersion` in
951
+ configuration when downgrade protection must survive process restarts.
952
+ Like Go, discovery fetches on each resolution, including renewal retries; it has
953
+ no built-in cache. Use static trust for high-volume opens, or supply a provider
954
+ with a deployment-owned refresh policy that refuses expired or failed-refresh trust.
955
+
956
+ ```ts
957
+ const opener = createPortalOpener({ qurl: signedLink, provider, transport: 'relay' });
958
+ ```
959
+
960
+ The SHA-pinned reviewed baseline and behavior gates are in `parity-manifest.json`.
961
+ CI reports the candidate SHA and tests that candidate against pinned Go behavior.
962
+ It does not require release or dependency PRs to match the baseline tree.
963
+ Run `npm run build`, `npm test`, `npm run smoke:dist`, and `npm run parity:go`.
964
+ Set `QURL_GO_REFERENCE` to a clean checkout at the manifest's exact Go revision.
965
+ The direct gate compares producer wire bytes and sealed-state reads and writes
966
+ across both languages. It also runs the TypeScript lifecycle against a local Go UDP
967
+ peer: registration, restart, relocation, exact retirement, and credential recovery.
968
+ This checks protocol interoperability; the peer is not a sandbox authority.
969
+ Shared conformance vectors cover assignment, registration,
970
+ OTP, and completion packet construction and reply decryption.
@@ -1,5 +1,5 @@
1
1
  import { ShareLink } from "./share.js";
2
- import type { AccessCodeListOutput, ApiKey, ApiKeyListOutput, ApiKeyRequestScope, BillingInvoiceListOutput, BatchCreateInput, BatchCreateOutput, ClientOptions, ConnectorInstallation, ConnectorInstallationListOutput, CreateAccessCodeInput, CreateAccessCodeOutput, CreateApiKeyInput, CreateApiKeyOutput, CreateBillingCheckoutInput, CreateInput, CreateOutput, CreatePortalOptions, CreateQurlForResourceInput, CreateResourceInput, CreateWebhookInput, Customer, CheckoutSession, Domain, DomainListOutput, DomainVerifyResult, ExtendInput, Invoice, ListInput, ListOutput, ListApiKeysInput, ListBillingInvoicesInput, ListConnectorInstallationsInput, ListDomainsInput, ListWebhookDeliveriesInput, ListWebhooksInput, MintInput, MintOutput, Portal, PortalSession, ProtectUrlOptions, QURL, QurlSummary, Quota, RedeemAccessCodeInput, RedeemAccessCodeOutput, RegisterDomainInput, Resource, ResourceDetail, ResourceHandle, ResourceListInput, ResourceListOutput, RequestOptions, ResolveInput, ResolveOutput, SessionListOutput, SessionTerminateOutput, ShareResourceOptions, UpdateApiKeyInput, UpdateCustomerInput, UpdateInput, UpdateResourceInput, UpdateResourceQurlInput, UpdateWebhookInput, UsageCurrentPeriod, UsageDaily, Webhook, WebhookDelivery, WebhookDeliveryListOutput, WebhookEventTypeInfo, WebhookListOutput, WebhookWithSecret } from "./types.js";
2
+ import type { AccessCodeListOutput, ApiKey, ApiKeyListOutput, ApiKeyRequestScope, BillingInvoiceListOutput, BatchCreateInput, BatchCreateOutput, ClientOptions, ConnectorInstallation, ConnectorInstallationListOutput, CreateAccessCodeInput, CreateAccessCodeOutput, CreateApiKeyInput, CreateApiKeyOutput, CreateBillingCheckoutInput, CreateDelegatedQurlBatchInput, CreateDelegatedQurlBatchOptions, CreateInput, CreateOutput, CreatePortalOptions, CreateQurlForResourceInput, CreateResourceInput, CreateWebhookInput, Customer, CheckoutSession, Domain, DomainListOutput, DomainVerifyResult, DelegatedQurl, DelegatedQurlBatchAccepted, GetDelegatedQurlBatchOptions, GetDelegatedQurlBatchOutput, ExtendInput, Invoice, ListInput, ListOutput, ListApiKeysInput, ListBillingInvoicesInput, ListConnectorInstallationsInput, ListDomainsInput, ListWebhookDeliveriesInput, ListWebhooksInput, MintInput, MintOutput, Portal, PortalSession, ProtectUrlOptions, QURL, QurlSummary, Quota, RedeemAccessCodeInput, RedeemAccessCodeOutput, RegisterDomainInput, Resource, ResourceDetail, ResourceHandle, ResourceListInput, ResourceListOutput, RequestOptions, ResolveInput, ResolveOutput, SessionListOutput, SessionTerminateOutput, ShareResourceOptions, UpdateApiKeyInput, UpdateCustomerInput, UpdateInput, UpdateResourceInput, UpdateResourceQurlInput, UpdateWebhookInput, UsageCurrentPeriod, UsageDaily, Webhook, WebhookDelivery, WebhookDeliveryListOutput, WebhookEventTypeInfo, WebhookListOutput, WebhookWithSecret } from "./types.js";
3
3
  /** Narrow a response scope before reusing it in a create/update request. */
4
4
  export declare function isApiKeyRequestScope(scope: string): scope is ApiKeyRequestScope;
5
5
  /**
@@ -226,6 +226,24 @@ export declare class QURLClient {
226
226
  * ```
227
227
  */
228
228
  batchCreate(input: BatchCreateInput, options?: RequestOptions): Promise<BatchCreateOutput>;
229
+ /**
230
+ * Start one durable delegated qURL batch. The SDK sends this mutation once.
231
+ * If the result may have committed, retry explicitly with the same key and
232
+ * semantic body.
233
+ */
234
+ createDelegatedQurlBatch(input: CreateDelegatedQurlBatchInput, options: CreateDelegatedQurlBatchOptions): Promise<DelegatedQurlBatchAccepted>;
235
+ /**
236
+ * Read one delegated qURL batch state. One call performs one logical read;
237
+ * callers retain control of the poll count and total deadline.
238
+ */
239
+ getDelegatedQurlBatch(batchId: string, options?: GetDelegatedQurlBatchOptions): Promise<GetDelegatedQurlBatchOutput>;
240
+ /** Read owner-visible metadata for one delegated qURL. */
241
+ getDelegatedQurl(qurlId: string): Promise<DelegatedQurl>;
242
+ /**
243
+ * Revoke one delegated qURL. DELETE is never retried automatically. A 503
244
+ * `mutation_outcome_unknown` is safe to retry with the same qURL ID.
245
+ */
246
+ deleteDelegatedQurl(qurlId: string): Promise<void>;
229
247
  /**
230
248
  * Get a qURL resource and its access tokens.
231
249
  *