@hushscript/sdk 1.0.1 → 1.1.1

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
@@ -395,11 +395,11 @@ Current prices are on [hushscript.com/pricing](https://hushscript.com/pricing).
395
395
 
396
396
  ## Requirements
397
397
 
398
- Node 22 or newer; CI tests Node 22, 24, and 26. Bun 1.2+ and Deno 2+ are checked for package
398
+ Node 24 or newer; CI tests Node 24 and 26. Bun 1.2+ and Deno 2+ are checked for package
399
399
  imports and a loopback HTTP balance request. HTTP/2 stream-reset and replay behavior in those
400
400
  runtimes is not tested. The SDK is for server runtimes only: a token in a browser bundle is a leaked token.
401
401
 
402
- The package is ESM-first: `import { ... } from "@hushscript/sdk"`. On Node 22.12 and newer,
402
+ The package is ESM-first: `import { ... } from "@hushscript/sdk"`. On Node 24 and newer,
403
403
  `require("@hushscript/sdk")` also works, because Node can `require()` an ES module (the `default`
404
404
  export condition points at the same ESM build). TypeScript consumers need TypeScript 5.5 or newer;
405
405
  `just build` type-checks the packed declarations with exactly 5.5 in a container.
@@ -426,10 +426,10 @@ Everything runs in containers; nothing touches a host toolchain. You need Docker
426
426
  [just](https://github.com/casey/just).
427
427
 
428
428
  ```sh
429
- just ci # lint, then test and conformance on Node 22, 24, and 26, then examples and build
429
+ just ci # lint, then test and conformance on Node 24 and 26, then examples and build
430
430
  just test 24 # unit tests with coverage on one runtime
431
431
  just lint # every static check
432
- just regen # regenerate openapi.json and src/generated from the production spec
432
+ just regen # regenerate openapi.json and src/generated by hand when the API changes (production spec, or a local file)
433
433
  ```
434
434
 
435
435
  The conformance mock is built from the `hushscript-sdk-conformance` repository at the tag or commit pinned in
package/dist/index.d.ts CHANGED
@@ -96,8 +96,8 @@ interface paths {
96
96
  cookie?: never;
97
97
  };
98
98
  /**
99
- * Read the account's balance, expiry and upload admission limits
100
- * @description Returns the caller's net credit balance, when that balance is next scheduled to expire without a completed transcription or purchase, whether a card is on file, the account's data region, and the account's current daily-minutes and concurrent-jobs limits. Call this before create_upload to confirm there is enough balance and daily headroom for the upload about to be attempted.
99
+ * Read the account's balance and upload admission limits
100
+ * @description Returns the caller's net credit balance, whether a card is on file, the account's data region, and the account's current daily-minutes and concurrent-jobs limits. Call this before create_upload to confirm there is enough balance and daily headroom for the upload about to be attempted.
101
101
  */
102
102
  get: operations["get_account"];
103
103
  put?: never;
@@ -137,7 +137,7 @@ interface paths {
137
137
  };
138
138
  /**
139
139
  * Fetch a page of presigned direct-to-R2 part URLs
140
- * @description Returns a fresh page of presigned PUT URLs for the given job's direct-to-R2 upload, starting at the requested part number. Presigned URLs expire, so a client resuming a stalled transfer should call this again rather than reusing URLs from create_upload's response.
140
+ * @description Returns a fresh page of presigned PUT URLs for the given job's direct-to-R2 upload, starting at the requested part number. Presigned URLs expire, so a client resuming a stalled transfer should call this again rather than reusing URLs from create_upload's response. Answers 404 when direct-to-R2 uploads are not available for the job; send the parts through upload_part then.
141
141
  */
142
142
  get: operations["get_upload_part_urls"];
143
143
  put?: never;
@@ -317,7 +317,7 @@ interface paths {
317
317
  };
318
318
  /**
319
319
  * List purchasable minute packs
320
- * @description Returns the account's minute-pack catalogue, priced in the account's own currency, including any referral buyer bonus currently available. Read the id of the pack to buy from here before calling buy_minutes. Needs the billing scope AND machine billing switched on for the account in the Hushscript app; either one off is a pat_scope_missing (code 2023) refusal, whichever it was.
320
+ * @description Returns the account's minute-pack catalogue, priced in the account's own currency, including any referral buyer bonus currently available. Read the id of the pack to buy from here before calling buy_minutes. Needs the billing scope, the token's own buy-minutes flag (set when the token is created), AND machine billing switched on for the account in the Hushscript app; any one off is a pat_scope_missing (code 2023) refusal, whichever it was.
321
321
  */
322
322
  get: operations["list_packs"];
323
323
  put?: never;
@@ -339,7 +339,7 @@ interface paths {
339
339
  put?: never;
340
340
  /**
341
341
  * Charge the account's saved default card for a minute pack
342
- * @description Charges a saved, fast_checkout_eligible payment method for one pack and credits the account's balance on success. quick_payment_method_id must be the account's current default, except when the account has no default at all, in which case naming an eligible card here makes it the new default. quick_payment_method_id is required: this API can only complete a purchase against a card already on file and has no way to open an interactive Checkout session, so an agent cannot use it to attach a new card. list_saved_cards can only list a card already on file, not create one; add a card first, either through the Hushscript app or by opening the hosted Checkout session create_setup_session returns. A request with no quick_payment_method_id, or a Quick Buy charge that needed authentication, a different payment method, or was declined, is refused outright rather than opened as a Checkout session nobody in this flow could complete. Needs the billing scope AND machine billing switched on for the account in the Hushscript app; either one off is a pat_scope_missing (code 2023) refusal, whichever it was.
342
+ * @description Charges a saved, fast_checkout_eligible payment method for one pack and credits the account's balance on success. quick_payment_method_id must be the account's current default, except when the account has no default at all, in which case naming an eligible card here makes it the new default. quick_payment_method_id is required: this API can only complete a purchase against a card already on file and has no way to open an interactive Checkout session, so an agent cannot use it to attach a new card. list_saved_cards can only list a card already on file, not create one; add a card first, either through the Hushscript app or by opening the hosted Checkout session create_setup_session returns. A request with no quick_payment_method_id, or a Quick Buy charge that needed authentication, a different payment method, or was declined, is refused outright rather than opened as a Checkout session nobody in this flow could complete. Needs the billing scope, the token's own buy-minutes flag (set when the token is created), AND machine billing switched on for the account in the Hushscript app; any one off is a pat_scope_missing (code 2023) refusal, whichever it was.
343
343
  */
344
344
  post: operations["buy_minutes"];
345
345
  delete?: never;
@@ -357,7 +357,7 @@ interface paths {
357
357
  };
358
358
  /**
359
359
  * List the account's saved payment methods
360
- * @description Returns every payment method saved on the account plus which one is the current default. This is the only source of a quick_payment_method_id for buy_minutes; it can only list a card already on file, not attach a new one. Needs the billing scope AND machine billing switched on for the account in the Hushscript app; either one off is a pat_scope_missing (code 2023) refusal, whichever it was.
360
+ * @description Returns every payment method saved on the account plus which one is the current default. This is the only source of a quick_payment_method_id for buy_minutes; it can only list a card already on file, not attach a new one. Needs the billing scope, the token's own buy-minutes flag (set when the token is created), AND machine billing switched on for the account in the Hushscript app; any one off is a pat_scope_missing (code 2023) refusal, whichever it was.
361
361
  */
362
362
  get: operations["list_saved_cards"];
363
363
  put?: never;
@@ -379,7 +379,7 @@ interface paths {
379
379
  put?: never;
380
380
  /**
381
381
  * Switch which saved card Quick Buy charges
382
- * @description Sets the given payment method as the account's default, which is the card buy_minutes charges when a caller sends its id as quick_payment_method_id. Use this to switch the default or to pick among multiple eligible cards; buy_minutes only adopts one automatically when the account has no default at all. The id must belong to a payment method already on file, from list_saved_cards; a well formed id this account does not own answers not found, exactly like one that is not a payment method at all. Needs the billing scope AND machine billing switched on for the account in the Hushscript app; either one off is a pat_scope_missing (code 2023) refusal, whichever it was.
382
+ * @description Sets the given payment method as the account's default, which is the card buy_minutes charges when a caller sends its id as quick_payment_method_id. Use this to switch the default or to pick among multiple eligible cards; buy_minutes only adopts one automatically when the account has no default at all. The id must belong to a payment method already on file, from list_saved_cards; a well formed id this account does not own answers not found, exactly like one that is not a payment method at all. Needs the billing scope, the token's own buy-minutes flag (set when the token is created), AND machine billing switched on for the account in the Hushscript app; any one off is a pat_scope_missing (code 2023) refusal, whichever it was.
383
383
  */
384
384
  post: operations["set_default_card"];
385
385
  delete?: never;
@@ -399,7 +399,7 @@ interface paths {
399
399
  put?: never;
400
400
  /**
401
401
  * Open a hosted Checkout Session that saves a card with no charge
402
- * @description Creates a Stripe Checkout Session in setup mode and returns its checkout_url. Open that URL in a browser you control (your own automation, not this API) so Stripe can render the card form and handle any bank authentication itself; card details never pass through this API. No charge is made. Once the caller completes the hosted page, the saved card becomes available from list_saved_cards and can be set as the default with set_default_card; list_saved_cards can lag a just-completed Session by up to 30 seconds, since nothing calls back into this API when the hosted page finishes, so retry rather than concluding the save failed. expires_at is when the Session stops accepting a card; call this endpoint again for a fresh link after that. idempotency_key is optional: omit it and every call opens a new Session, which is safe since a setup Session is never charged and expires on its own; supply your own key only if you want a retried call to land on the same Session instead. Needs the billing scope AND machine billing switched on for the account in the Hushscript app; either one off is a pat_scope_missing (code 2023) refusal, whichever it was.
402
+ * @description Creates a Stripe Checkout Session in setup mode and returns its checkout_url. Open that URL in a browser you control (your own automation, not this API) so Stripe can render the card form and handle any bank authentication itself; card details never pass through this API. No charge is made. Once the caller completes the hosted page, the saved card becomes available from list_saved_cards and can be set as the default with set_default_card; list_saved_cards can lag a just-completed Session by up to 30 seconds, since nothing calls back into this API when the hosted page finishes, so retry rather than concluding the save failed. expires_at is when the Session stops accepting a card; call this endpoint again for a fresh link after that. idempotency_key is optional: omit it and every call opens a new Session, which is safe since a setup Session is never charged and expires on its own; supply your own key only if you want a retried call to land on the same Session instead. Needs the billing scope, the token's own buy-minutes flag (set when the token is created), AND machine billing switched on for the account in the Hushscript app; any one off is a pat_scope_missing (code 2023) refusal, whichever it was.
403
403
  */
404
404
  post: operations["create_setup_session"];
405
405
  delete?: never;
@@ -477,7 +477,7 @@ interface paths {
477
477
  };
478
478
  /**
479
479
  * Read the caller's organization summary
480
- * @description A pure passthrough of GET /api/org's body: plan state and term, pool balance and expiry, retention policy, tax id, auto-renewal source and failure count, the workspace-wide default per-member cap, and the caller's own effective cap and month-to-date spend against the pool. Membership only, not admin -- renewal_user_id is visible to admins only.
480
+ * @description A pure passthrough of GET /api/org's body: plan state and term, pool balance, retention policy, tax id, auto-renewal source and failure count, the workspace-wide default per-member cap, and the caller's own effective cap and month-to-date spend against the pool. Membership only, not admin -- renewal_user_id is visible to admins only.
481
481
  */
482
482
  get: operations["get_org"];
483
483
  put?: never;
@@ -803,7 +803,7 @@ interface paths {
803
803
  put?: never;
804
804
  /**
805
805
  * Claim a paid agent signup into a real account
806
- * @description Exchanges a paid, unclaimed agent signup for the account it pays for. Presents the claim_secret returned once by POST /v1/agent/accounts; a wrong secret, an unknown signup_id, an already claimed signup, a refunded signup, and an expired signup all answer the identical agent_claim_invalid error so a caller can never learn which of those is true. Only once that secret checks out does payment state matter: a signup whose Checkout Session has not settled to paid answers wrong_state instead. A successful claim is single use; creates exactly one account with a synthetic, unresolvable login identity; grants the paid pack once, never twice, even on a retried request; and mints exactly one personal access token with the account's own agent scopes, returned only in this response.
806
+ * @description Exchanges a paid, unclaimed agent signup for the account it pays for. Presents the claim_secret returned once by POST /v1/agent/accounts; a wrong secret, an unknown signup_id, an already claimed signup whose token can no longer be re-minted, a refunded signup, and an expired signup all answer the identical agent_claim_invalid error so a caller can never learn which of those is true. Only once that secret checks out does payment state matter: a signup whose Checkout Session has not settled to paid answers wrong_state instead. A successful claim creates exactly one account with a synthetic, unresolvable login identity, grants the paid pack once, never twice, even on a retried request, and mints one personal access token with the account's own agent scopes. Only the token's hash is stored. If the 201 is lost, repeat the request with the same claim_secret: while that token has not yet made a successful request, and for up to one hour after it was minted, the retry answers 201 with the same user_id, no second pack grant and a NEW token for the same account; the lost token stops working. Making one successful call with the new token ends the window, and the same request then answers agent_claim_invalid again. A late-landing earlier retry can replace the secret of the token you hold, so make that one call right away, and if it answers 401 within the hour, repeat the claim. A retry that overlaps a first claim still in flight answers rate_limited with Retry-After: 2 or re-mints. Until the token is first used or one hour has passed, the claim_secret works as a credential for the account, so keep it private.
807
807
  */
808
808
  post: operations["claim_agent_account"];
809
809
  delete?: never;
@@ -823,7 +823,7 @@ interface paths {
823
823
  put?: never;
824
824
  /**
825
825
  * Rotate the calling agent PAT
826
- * @description Atomically mints a successor personal access token and revokes the one that authenticated this request. A machine account has no password and no usable mailbox, so this is its only way to rotate a leaked credential. The successor keeps the predecessor's scopes, billing_enabled flag, name, client_label, and expiry policy; only the secret changes. The predecessor fails authentication on the very next request. This route references no token but the one that called it: it cannot list, mint, or revoke any other credential.
826
+ * @description Atomically mints a successor personal access token for the one that authenticated this request. A machine account has no password and no usable mailbox, so this is its only way to rotate a leaked credential. The successor keeps the predecessor's scopes, billing_enabled flag, name, client_label, and expiry policy; only the secret changes. The predecessor is not revoked at once. It stays in a grace period that ends at the successor's first successful request or one hour after the rotation, whichever comes first. During that period it authenticates only this route, and every other route answers it with a bare 401. If the 201 is lost, call this route again with the predecessor while the successor is still unused: the response carries the same pat_id and a NEW secret, and the earlier successor secret stops working. Keep the predecessor until the successor has made one successful call, because a late-landing earlier retry can replace the successor's secret. Then make one call with the successor right away to retire the predecessor. Once the successor has been used or the hour has passed, the predecessor is refused here as well. This route references no token but the one that called it and that token's own successor: it cannot list, mint, or revoke any other credential.
827
827
  */
828
828
  post: operations["rotate_agent_credentials"];
829
829
  delete?: never;
@@ -850,8 +850,10 @@ interface components {
850
850
  /** @description The organization's shared pool balance in seconds. Present on an org-funded balance-shortfall error instead of balance_seconds. */
851
851
  org_balance_seconds?: number;
852
852
  limits?: components["schemas"]["UploadLimits"];
853
- /** @description Structured recovery detail for an error that is not a plain balance shortfall. Present on agent_pack_locked and agent_purchase_capped. */
853
+ /** @description Structured recovery detail for an error that is not a plain balance shortfall. Present on agent_pack_locked, agent_purchase_capped and policy_version_stale. */
854
854
  details?: {
855
+ /** @description The server's current terms version. Present on policy_version_stale; send it as accept_terms_version to retry. */
856
+ current_version?: string;
855
857
  /** @description Pack ids the agent account may buy right now. Present on agent_pack_locked; retry with one of these. */
856
858
  allowed_packs?: string[];
857
859
  /** @description The per-credential purchase cap for the rolling window. Present on agent_purchase_capped. */
@@ -878,12 +880,14 @@ interface components {
878
880
  balance_seconds: number;
879
881
  /** @description Seconds currently committed to in-flight jobs and not yet settled. */
880
882
  held_seconds: number;
881
- /** @description Unix seconds after which the balance expires without a completed transcription or purchase, or null if no expiry is currently armed. */
883
+ /** @description Always null; minutes do not expire. Retained for compatibility until the next SDK major version. */
882
884
  credits_expire_at: number | null;
883
885
  card_on_file: boolean;
884
886
  /** @description The region this account's data lives in, e.g. us, eu, apac or oc. */
885
887
  data_region: string;
886
888
  limits: components["schemas"]["UploadLimits"];
889
+ /** @description Agent accounts only: how many purchases are still available in the current rolling window, never below 0. Absent for human accounts. */
890
+ purchases_remaining_in_window?: number;
887
891
  };
888
892
  PresignedPartUrl: {
889
893
  /** @description The 1-based part number this URL is for. */
@@ -946,7 +950,7 @@ interface components {
946
950
  };
947
951
  Job: {
948
952
  id: string;
949
- /** @description One of uploading, fetching, queued, processing, done or failed. */
953
+ /** @description One of uploading, fetching, queued, processing, awaiting_unlock, done or failed. */
950
954
  state: string;
951
955
  mode: string;
952
956
  declared_seconds: number;
@@ -1141,7 +1145,7 @@ interface components {
1141
1145
  created_at: number;
1142
1146
  deleted_at: number;
1143
1147
  /**
1144
- * @description Which deletion path removed the transcript: an explicit delete (manual), the transcript's own auto_delete_at retention date (scheduled), the dormant-account purge (dormant), or the global retention sweep (expired).
1148
+ * @description Which deletion path removed the transcript: an explicit delete (manual), the transcript's own auto_delete_at retention date (scheduled), the personal-transcript purge after about 24 months of account inactivity and a 30-day warning (dormant; excludes legal holds and firm custody), or the global retention sweep (expired).
1145
1149
  * @enum {string}
1146
1150
  */
1147
1151
  cause: "manual" | "scheduled" | "dormant" | "expired";
@@ -1355,7 +1359,7 @@ interface components {
1355
1359
  AgentClaimResponse: {
1356
1360
  /** @description The account created by this claim. There is no login path for it; authenticate with pat instead. */
1357
1361
  user_id: string;
1358
- /** @description Returned exactly once. Only its hash is stored; there is no way to recover it later. */
1362
+ /** @description Only its hash is stored; there is no way to recover it later. A retry of the claim while this token is unused and within one hour of the mint returns a new token for the same account. */
1359
1363
  pat: string;
1360
1364
  /** @description The scopes carried by pat. */
1361
1365
  scopes: string[];
@@ -1363,7 +1367,7 @@ interface components {
1363
1367
  balance_seconds: number;
1364
1368
  };
1365
1369
  AgentCredentialsRotateResponse: {
1366
- /** @description The successor token, returned exactly once. Only its hash is stored; there is no way to recover it later. The predecessor that authenticated this request stops working immediately. */
1370
+ /** @description The successor token. Only its hash is stored; there is no way to recover it later. A repeated call with the predecessor while this token is unused returns a new secret for the same pat_id. The predecessor keeps working for this route only, until the successor's first successful request or one hour, whichever comes first. */
1367
1371
  pat: string;
1368
1372
  /** @description The successor's id. */
1369
1373
  pat_id: string;
@@ -1395,7 +1399,7 @@ interface components {
1395
1399
  balance_seconds: number;
1396
1400
  /** @description balance_seconds floored at zero, and zeroed outright when the org is outside its funding window (frozen or lapsed past grace). */
1397
1401
  spendable_seconds: number;
1398
- /** @description Unix seconds the pool's own rolling 365-day expiry falls at, re-anchored on every credit and every settle. Null if the pool has never held a positive balance. */
1402
+ /** @description Always null; minutes do not expire. Retained for compatibility until the next SDK major version. */
1399
1403
  pool_expires_at: number | null;
1400
1404
  default_retention_days: number | null;
1401
1405
  max_retention_days: number | null;
@@ -1514,7 +1518,7 @@ interface operations {
1514
1518
  requestBody: {
1515
1519
  content: {
1516
1520
  "application/json": {
1517
- /** @description The exact declared byte size of the audio file, up to the 5 GB cap. */
1521
+ /** @description The exact declared byte size of the audio file, from 1 byte up to the 5 GB cap. */
1518
1522
  size_bytes: number;
1519
1523
  /** @description The declared duration in seconds, from 15 seconds up to the 10 hour cap. Rechecked against the probed exact duration at complete_upload. */
1520
1524
  duration_seconds: number;
@@ -1649,7 +1653,7 @@ interface operations {
1649
1653
  part_urls: components["schemas"]["PresignedPartUrl"][];
1650
1654
  /** @description The next part number not covered by this page, or null once every part has a URL. */
1651
1655
  next_part_number: number | null;
1652
- } | null;
1656
+ };
1653
1657
  };
1654
1658
  };
1655
1659
  /** @description Error response. */
@@ -3646,7 +3650,10 @@ interface operations {
3646
3650
  parameters: {
3647
3651
  query?: never;
3648
3652
  header?: never;
3649
- path?: never;
3653
+ path: {
3654
+ /** @description The signup id returned by agent signup. */
3655
+ signup_id: string;
3656
+ };
3650
3657
  cookie?: never;
3651
3658
  };
3652
3659
  requestBody: {
@@ -3764,6 +3771,7 @@ interface Account {
3764
3771
  balanceSeconds: number;
3765
3772
  /** Committed to in-flight jobs; already deducted from `balanceSeconds`. */
3766
3773
  heldSeconds: number;
3774
+ /** Always null; minutes do not expire. Kept for compatibility. */
3767
3775
  creditsExpireAt: Date | null;
3768
3776
  cardOnFile: boolean;
3769
3777
  /** For example `us`, `eu`, `apac` or `oc`. */
@@ -3780,6 +3788,7 @@ interface Balance {
3780
3788
  minutes: number;
3781
3789
  /** Committed to in-flight jobs; already deducted from `seconds`. */
3782
3790
  heldSeconds: number;
3791
+ /** Always null; minutes do not expire. Kept for compatibility. */
3783
3792
  expiresAt: Date | null;
3784
3793
  /** Agent accounts only, else null. */
3785
3794
  purchasesRemaining: number | null;
@@ -4363,4 +4372,5 @@ declare const HINTS: Record<string, string>;
4363
4372
 
4364
4373
  declare const OPERATION_SCOPES: Record<string, string>;
4365
4374
 
4366
- export { AbortError, type Account, type AgentClaim, type AgentSignup, type AgentSignupRequest, type AgentStatic, ApiError, AuthenticationError, type Balance, type BuyOptions, type CaptionOptions, type Card, type Cards, type Clock, ConfigurationError, ConflictError, DailyLimitError, type DeletedTranscript, ERROR_CATALOG, type ErrorCatalogEntry, type FileInput, FileLimitError, HINTS, type Hold, Hushscript, HushscriptError, type HushscriptOptions, InsufficientBalanceError, type Job, JobFailedError, type JobOptions, type JobState, type JobWaitOptions, type LanguageOptions, type LedgerEntry, type Money, NetworkError, NotFoundError, OPERATION_SCOPES, OutcomeUnknownError, type Pack, type Page, type PageOptions, type PageRequest, PaymentMethodRequiredError, PermissionDeniedError, PreflightError, type Progress, type Purchase, RateLimitError, ResumeMismatchError, type ResumeOptions, type ResumeToken, type RotatedToken, type TextOptions, type Transaction, type TranscribeOptions, Transcript, type TranscriptSummary, UnsupportedMediaError, UploadError, type UploadLimits, type Utterance, ValidationError, WaitTimeoutError, type components, type operations, paginate, type paths };
4375
+ export { AbortError, ApiError, AuthenticationError, ConfigurationError, ConflictError, DailyLimitError, ERROR_CATALOG, FileLimitError, HINTS, Hushscript, HushscriptError, InsufficientBalanceError, JobFailedError, NetworkError, NotFoundError, OPERATION_SCOPES, OutcomeUnknownError, PaymentMethodRequiredError, PermissionDeniedError, PreflightError, RateLimitError, ResumeMismatchError, Transcript, UnsupportedMediaError, UploadError, ValidationError, WaitTimeoutError, paginate };
4376
+ export type { Account, AgentClaim, AgentSignup, AgentSignupRequest, AgentStatic, Balance, BuyOptions, CaptionOptions, Card, Cards, Clock, DeletedTranscript, ErrorCatalogEntry, FileInput, Hold, HushscriptOptions, Job, JobOptions, JobState, JobWaitOptions, LanguageOptions, LedgerEntry, Money, Pack, Page, PageOptions, PageRequest, Progress, Purchase, ResumeOptions, ResumeToken, RotatedToken, TextOptions, Transaction, TranscribeOptions, TranscriptSummary, UploadLimits, Utterance, components, operations, paths };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { stat, open } from 'fs/promises';
9
9
 
10
10
  // package.json
11
11
  var package_default = {
12
- version: "1.0.1"};
12
+ version: "1.1.1"};
13
13
 
14
14
  // src/clock.ts
15
15
  var systemClock = {
@@ -59,7 +59,7 @@ function camelizeKnown(raw, known) {
59
59
  var ERROR_CATALOG = {
60
60
  "bad_request": { code: 1e3, status: 400, meaning: "The request body could not be parsed, or a required field was missing. Check the request against this operation's schema and resend." },
61
61
  "invalid_email": { code: 1001, status: 400, meaning: "The email address failed format or safety validation (address lists, spoofed display names, control characters and quoted local parts are all rejected). Send a single plain address." },
62
- "invalid_password": { code: 1002, status: 400, meaning: "The password did not meet the length bounds this API enforces. Choose a password between the documented minimum and maximum byte length." },
62
+ "invalid_password": { code: 1002, status: 400, meaning: "A new password (register or set-password) did not meet the policy: at least 12 characters, at most 256 bytes, with at least one letter and one digit. Existing passwords still sign in; the rule applies only when setting one." },
63
63
  "missing_token": { code: 1003, status: 400, meaning: "No longer emitted: GET /api/auth/verify without a token now redirects to the app with ?error=link_expired instead of returning this JSON error. It stays in the catalog, with its code, slug and status unchanged, for clients that may still key on it." },
64
64
  "invalid_locale": { code: 1004, status: 400, meaning: "The requested locale is not one this account or API supports. Use one of the documented locale codes." },
65
65
  "bad_part_number": { code: 1005, status: 400, meaning: "The part number is outside the plan for this upload (below 1 or past the last part for the declared size). Recompute the part count from the declared size and part size." },
@@ -88,7 +88,9 @@ var ERROR_CATALOG = {
88
88
  "invalid_idempotency_key": { code: 1040, status: 422, meaning: "The supplied idempotency_key was outside the accepted length bounds. Send a key between the documented minimum and maximum length, or omit it." },
89
89
  "upload_incomplete": { code: 1041, status: 422, meaning: "The assembled object was shorter than the size declared at creation, so the hold was released and nothing was billed. Re-upload every part and call complete again." },
90
90
  "url_target_busy": { code: 1042, status: 429, meaning: "This API is already fetching from that target host as fast as it will, so the fetch was refused before it was attempted. This bounds the target site, not the caller: a different source URL will go through immediately, and the same one will after a short wait." },
91
- "policy_version_stale": { code: 1043, status: 422, meaning: "accept_terms_version did not match the server's current policy version. The server records its own value, never the caller's, so retry with the current version returned by this same error." },
91
+ "policy_version_stale": { code: 1043, status: 422, meaning: "accept_terms_version did not match the server's current policy version. The server records its own value, never the caller's, so retry with the current version, which this same error names in details.current_version." },
92
+ "terms_acceptance_required": { code: 1044, status: 422, meaning: "A first Apple or Google sign-in creates an account, so the current terms version must be accepted. Send the version in accept_terms_version; details.current_version names the value to send." },
93
+ "password_reused": { code: 1045, status: 400, meaning: "The new password equals the account's current password or one of the three before it. Choose a password that differs from the last four. Each comparison counts against the same hourly failure limit as a wrong current password." },
92
94
  "unauthorized": { code: 2e3, status: 401, meaning: "The bearer token is missing, malformed, expired, or revoked. This is also the answer for a revoked, malformed, or unknown Personal Access Token, so a caller holding a PAT should mint a fresh one rather than retry the same one. Obtain a fresh session token or Personal Access Token and retry with it in the Authorization header." },
93
95
  "invalid_credentials": { code: 2001, status: 401, meaning: "The submitted email/password pair did not match an account. Check the credentials or use the password-reset flow." },
94
96
  "turnstile_failed": { code: 2010, status: 403, meaning: "The Cloudflare Turnstile challenge could not be verified. Re-run the challenge on the client and resend with a fresh token." },
@@ -99,11 +101,14 @@ var ERROR_CATALOG = {
99
101
  "org_required": { code: 2021, status: 403, meaning: "This action requires the caller to belong to an organization, and the bearer does not. Join or create an organization first. PATCH /api/org also answers it, writing nothing, when the patch names a field whose right the caller lacks: the billing contact, tax identity and auto_renew need the billing right, every other field the admin right. POST /api/org/invites and PATCH /api/org/members/:user_id answer it too when they hand out or take away the billing right (an invite carrying an explicit is_billing true; a patch naming is_billing) for a caller who does not hold it, except that while no member of the workspace holds the right any admin may grant it (a revoke always needs it). A workspace member removal answers it too when the target holds the billing right and the caller neither holds it nor is that member (a member may always leave; removing a holder needs the right, so the recovery rule above is reachable only after the last holder leaves, revokes their own right, or deletes their account). An invite that leaves is_billing out defaults it to the caller's own right for role admin, so an admin without the billing right inviting an admin sends a plain admin invite and is not refused." },
100
102
  "pat_forbidden": { code: 2022, status: 403, meaning: "This route is not in the Personal Access Token scope map at all, so no token, regardless of scope, can reach it. Use a session bearer for this call instead." },
101
103
  "pat_scope_missing": { code: 2023, status: 403, meaning: "The Personal Access Token does not carry the scope this route requires (see x-required-scope on the operation). Mint or use a token that includes it." },
102
- "step_up_required": { code: 2024, status: 403, meaning: "Deleting an account needs proof it is the holder asking. DELETE /api/me carried neither current_password nor email_code, or sent current_password for a password set or changed in the last 7 days, or one the requesting session itself set. Send the current password (set more than 7 days ago, not by this session), or a code sent by POST /api/me/deletion-code." },
104
+ "step_up_required": { code: 2024, status: 403, meaning: "Deleting an account needs proof it is the holder asking. DELETE /api/me carried neither current_password nor email_code, or sent current_password for a password set or changed in the last 7 days, or one the requesting session itself set. Send the current password (set more than 7 days ago, not by this session), a code sent by POST /api/me/deletion-code, or a reauth_grant from a fresh Apple or Google re-authentication. Unlinking a sign-in method needs the same proof unless the session is under 15 minutes old." },
105
+ "id_token_invalid": { code: 2025, status: 401, meaning: "The Apple or Google ID token failed verification: signature, issuer, audience, nonce, age, replay or shape. The cause is never reported to the caller." },
106
+ "identity_email_unverified": { code: 2026, status: 403, meaning: "The Apple or Google account has no verified email address, so no account can be created or matched from it. Verify the email with the provider or sign in another way." },
103
107
  "card_required": { code: 3e3, status: 402, meaning: "No longer emitted: no current route returns this code. It stays in the catalog, with its code, slug and status unchanged, for clients that may still key on it. It used to mean: This purchase needs a card on file and the account has none. Add a card through the account's payment settings before retrying." },
104
108
  "insufficient_balance": { code: 3001, status: 402, meaning: "The account's balance cannot cover the requested seconds. The error body's needed_seconds and balance_seconds report the shortfall; top up before retrying." },
105
109
  "card_declined": { code: 3002, status: 402, meaning: "No longer emitted: no current route returns this code. It stays in the catalog, with its code, slug and status unchanged, for clients that may still key on it. It used to mean: The card on file was declined when charged. Use a different payment method or contact the card issuer." },
106
110
  "org_insufficient_balance": { code: 3003, status: 402, meaning: "The organization's shared minute pool cannot cover the requested seconds. The error body's org_balance_seconds reports the pool's current balance; an org admin must top it up." },
111
+ "preview_not_eligible": { code: 3004, status: 409, meaning: "The account or upload is not eligible for an account preview. An eligible upload must be gated and must not have finished or failed." },
107
112
  "not_found": { code: 4e3, status: 404, meaning: "No resource exists at this id for the authenticated caller. Confirm the id and that it belongs to this account." },
108
113
  "wrong_state": { code: 4001, status: 409, meaning: "The target resource is not in a state this action allows (for example, an upload that already finished). Read its current state before retrying." },
109
114
  "email_exists": { code: 4002, status: 409, meaning: "An account already exists for this email address. Sign in instead of registering again." },
@@ -124,13 +129,13 @@ var ERROR_CATALOG = {
124
129
  "org_retention_too_loose": { code: 4017, status: 409, meaning: "The requested retention setting exceeds the organization's configured maximum. Request a value at or below the org's ceiling." },
125
130
  "org_plan_invoice_open": { code: 4018, status: 409, meaning: "The organization already has an open, unpaid plan invoice. Settle or wait for it to be superseded before requesting another." },
126
131
  "pat_exchange_invalid": { code: 4019, status: 410, meaning: "The OAuth handoff exchange code is invalid, already used, or expired. Restart the handoff flow to obtain a new code." },
127
- "pat_invalid": { code: 4020, status: 422, meaning: "The POST /api/pats request body failed validation: an empty or oversized name, an unknown or empty scope list, created_via outside app or oauth, or an invalid client_label. Fix the request body and retry. A bearer token that is itself malformed, revoked, or unknown never reaches this code; that case answers unauthorized (2000) instead." },
132
+ "pat_invalid": { code: 4020, status: 422, meaning: "The POST /api/pats request body failed validation: an empty or oversized name, an unknown or empty scope list, created_via outside app, oauth or extension, or an invalid client_label. Fix the request body and retry. A bearer token that is itself malformed, revoked, or unknown never reaches this code; that case answers unauthorized (2000) instead." },
128
133
  "pat_purchase_requires_app": { code: 4021, status: 403, meaning: "This purchase needs full Checkout, which this API cannot open or let the caller complete. Either the request had no quick_payment_method_id, in which case resend with one set to a card already on file (see GET /v1/billing/cards), or the saved card will not go through as attempted (declined, needs a different payment method, or was canceled), in which case retrying the same card changes nothing: fix or replace it, then retry with a brand new idempotency_key, or complete the purchase from the Hushscript app. A card whose issuer wants an interactive challenge is not a decline and answers 4023 instead." },
129
134
  "pat_limit": { code: 4022, status: 409, meaning: "The account already holds the maximum number of Personal Access Tokens. Revoke an unused token before minting another." },
130
135
  "pat_purchase_requires_authentication": { code: 4023, status: 403, meaning: "The saved card is fine, but the issuer wants a challenge (3DS) before this charge can go through. This API cannot open or let the caller complete that challenge, so the purchase is refused rather than left pending. Complete the purchase from the Hushscript app instead, where the holder can go through authentication." },
131
136
  "org_signups_closed": { code: 4024, status: 403, meaning: "Creating a new organization is closed in this environment. Signups are open in every environment today, so this answers only where they were deliberately closed again. Existing organizations keep working normally; every other org route, including renewals, pack purchases, invites, and admin reads, stays open." },
132
137
  "org_plan_frozen": { code: 4025, status: 402, meaning: "The organization's plan lapsed and its 30 day grace window has also passed, so no new organization funded upload is admitted. A job already running still settles normally. Paying a plan renewal clears the freeze right away." },
133
- "org_pool_expired": { code: 4026, status: 402, meaning: "The organization's shared minute pool is present but its 365-day rolling clock has lapsed with no purchase, grant, or completed job to renew it. A pack purchase, an included plan grant, or completing another org-funded job all restart the clock for another year." },
138
+ "org_pool_expired": { code: 4026, status: 402, meaning: "No longer emitted: minutes do not expire. Code, slug, and status remain reserved for existing clients." },
134
139
  "org_member_cap_exceeded": { code: 4027, status: 402, meaning: "This pool member has used their whole monthly share of the workspace's pooled seconds. The workspace pool itself may still have a balance; this is the per-member cap, separate from a plain insufficient-balance refusal." },
135
140
  "org_renewal_payment_failed": { code: 4028, status: 402, meaning: "The daily renewal lane charged the organization's stored renewal card and Stripe answered with a structured failure. The invoice stays issued, the failure count goes up by one, a renewal-failed email carrying a fresh Checkout link for that same invoice is sent (flagged as the final attempt once the count reaches the cap of 3), and the lapsed term falls into the ordinary grace window. Once the cap is reached the lane stops retrying this organization automatically -- no further charge attempts, no further emails -- until the open invoice is paid by hand, which resets the count. GET /api/org exposes this as a derived renewal_capped boolean." },
136
141
  "org_no_default_payment_method": { code: 4029, status: 409, meaning: "The chosen payment method is not one of the caller's own saved, fast checkout eligible cards, the caller has no Stripe customer at all, or auto renew was switched on with no renewal card stored yet. All three answer identically so this route can never be used to learn whether a given payment method id exists." },
@@ -139,7 +144,7 @@ var ERROR_CATALOG = {
139
144
  "org_refund_currency_mismatch": { code: 4032, status: 409, meaning: "No longer emitted: no current route returns this code. It stays in the catalog, with its code, slug and status unchanged, for clients that may still key on it. The signed admin fee-refund command answers its own currency_mismatch refusal instead. It used to mean: The Stripe charge settled in a currency different from the invoice's currency, so a partial refund amount cannot be computed. Contact support for a manual refund." },
140
145
  "org_tax_id_invalid": { code: 4033, status: 400, meaning: "The tax id or its label does not match a shape this system accepts. This is a shape check only, never a registry lookup against a tax authority." },
141
146
  "agent_signup_pending": { code: 4035, status: 409, meaning: "A signup already exists for this contact_email and has not yet been claimed, refunded, or expired. Wait for it to resolve or use a different contact address." },
142
- "agent_claim_invalid": { code: 4036, status: 401, meaning: "The claim secret did not match, or the signup does not exist, has already been claimed, was refunded, or has expired. These cases answer identically on purpose. A confirmed-but-unpaid Checkout Session answers wrong_state (4001) instead once the secret itself has checked out." },
147
+ "agent_claim_invalid": { code: 4036, status: 401, meaning: "The claim secret did not match, or the signup does not exist, was refunded, or has expired, or it was already claimed and the claim token can no longer be re-minted (it was used, revoked, or one hour has passed since it was minted). These cases answer identically on purpose. A correct-secret retry of a completed claim whose token is still unused and within that hour answers 201 with a new token instead. A confirmed-but-unpaid Checkout Session answers wrong_state (4001) instead once the secret itself has checked out." },
143
148
  "agent_pack_locked": { code: 4037, status: 403, meaning: "An agent account's pack tier does not allow the requested pack yet. A fresh agent account is limited to the small packs; a larger pack unlocks only once enough prior payments have settled past the dispute window. Reached on POST /v1/agent/accounts (signup, always tier 0) and POST /v1/billing/purchase for an agent caller. The response carries details.allowed_packs, the pack ids currently buyable; retry with one of those. Never reached by a human account." },
144
149
  "agent_purchase_capped": { code: 4038, status: 429, meaning: "An agent account has reached its per-credential spend cap for the current rolling window: 3 purchases, paid or declined, in the trailing 24 hours. The cap is counted per account across every credential the account has ever held, not per token, so rotating a credential does not reset it. Reached on POST /v1/billing/purchase for an agent caller, and for a human account's personal access token caller, which has its own cap of the same size counted the same way. A human purchasing through the app is never capped. The response carries details.limit, details.window_seconds and details.retry_after_seconds, and a Retry-After header naming the same wait in seconds." },
145
150
  "org_last_admin": { code: 4039, status: 409, meaning: "A rights change or a member removal would leave the workspace with no member carrying is_admin. This is refused by a count check evaluated inside the update itself, not by a pre-read, so two admins concurrently dropping each other's flag cannot both succeed." },
@@ -171,6 +176,10 @@ var ERROR_CATALOG = {
171
176
  "org_client_closed": { code: 4069, status: 409, meaning: "That client is closed, so its matters cannot take new work either." },
172
177
  "org_client_limit": { code: 4070, status: 409, meaning: "This workspace has reached its configured client limit." },
173
178
  "deletion_code_invalid": { code: 4071, status: 422, meaning: "The email_code sent to DELETE /api/me is wrong, expired, already used, or has had five wrong guesses. Request a new code with POST /api/me/deletion-code." },
179
+ "identity_already_linked": { code: 4072, status: 409, meaning: "This account already has a different Apple or Google account linked, or this provider account belongs to another user. Sign in with the linked account instead." },
180
+ "identity_last_method": { code: 4073, status: 409, meaning: "Unlinking would leave the account with no way to sign in; add a password or another sign-in method first." },
181
+ "identity_mismatch": { code: 4074, status: 403, meaning: "The provider account used to confirm this action is not the one linked to this account." },
182
+ "job_not_awaiting_unlock": { code: 4075, status: 409, meaning: "The job is not parked awaiting credit and cannot be started from its current state." },
174
183
  "rate_limited": { code: 5e3, status: 429, meaning: "The caller has been rate limited. PAT-authenticated traffic carries a Retry-After header naming the wait in seconds; other rate-limited routes may not." },
175
184
  "too_many_active_jobs": { code: 5001, status: 429, meaning: "The account already has the maximum number of concurrent pipeline jobs in flight. Wait for one to finish before starting another." },
176
185
  "ai_cap_reached": { code: 5002, status: 503, meaning: "The Insights provider's own capacity is temporarily exhausted. Retry the generation after a short delay." },
@@ -178,6 +187,7 @@ var ERROR_CATALOG = {
178
187
  "provider_error": { code: 6001, status: 502, meaning: "The transcription provider returned an error or could not be reached. This is usually transient; retry after a delay." },
179
188
  "stripe_error": { code: 6002, status: 502, meaning: "The payment provider returned an error or could not be reached. This is usually transient; retry after a delay." },
180
189
  "email_error": { code: 6003, status: 502, meaning: "The transactional email provider could not be reached or refused the message. Not directly actionable by an API caller; the underlying action may still have succeeded." },
190
+ "identity_provider_unavailable": { code: 6010, status: 503, meaning: "Apple or Google sign-in is turned off or the provider could not be reached. Try again later or use another sign-in method." },
181
191
  "internal_error": { code: 9e3, status: 500, meaning: "An unexpected server-side failure occurred. Retry later; if it persists, it is a bug on the backend, not the request." },
182
192
  "transcript_data_missing": { code: 9001, status: 500, meaning: "No longer emitted: no current route returns this code. It stays in the catalog, with its code, slug and status unchanged, for clients that may still key on it. It used to mean: The transcript's stored body could not be found or read where this action expected it. Treat as a transient storage fault and retry, or contact support if it persists." }
183
193
  };
@@ -1564,15 +1574,15 @@ var ACCOUNT_FIELDS = /* @__PURE__ */ new Set([
1564
1574
  "credits_expire_at",
1565
1575
  "card_on_file",
1566
1576
  "data_region",
1567
- "limits"
1568
- ],
1569
- "purchases_remaining_in_window"
1577
+ "limits",
1578
+ "purchases_remaining_in_window"
1579
+ ]
1570
1580
  ]);
1571
1581
  function expiry(raw) {
1572
1582
  return raw.credits_expire_at === null ? null : new Date(raw.credits_expire_at * 1e3);
1573
1583
  }
1574
1584
  function purchasesRemaining(raw) {
1575
- const remaining = raw["purchases_remaining_in_window"];
1585
+ const remaining = raw.purchases_remaining_in_window;
1576
1586
  return typeof remaining === "number" && Number.isSafeInteger(remaining) && remaining >= 0 ? remaining : null;
1577
1587
  }
1578
1588
  function toAccount(raw) {
@@ -1991,8 +2001,6 @@ var agentStatic = {
1991
2001
  const api = tokenlessApi(options.baseUrl);
1992
2002
  const { status, body } = await readObject(
1993
2003
  api.POST("/v1/agent/accounts/{signup_id}/claim", {
1994
- // The OpenAPI document leaves the {signup_id} path parameter out of this operation, so its
1995
- // generated type has no `path`; openapi-fetch still fills the template from it.
1996
2004
  params: { path: { signup_id: signupId } },
1997
2005
  body: { claim_secret: claimSecret },
1998
2006
  parseAs: "text"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hushscript/sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Official TypeScript SDK for the Hushscript transcription API.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,7 +13,7 @@
13
13
  "url": "https://github.com/Hushscript/hushscript-sdk-typescript/issues"
14
14
  },
15
15
  "engines": {
16
- "node": ">=22"
16
+ "node": ">=24"
17
17
  },
18
18
  "sideEffects": false,
19
19
  "files": [
@@ -41,34 +41,37 @@
41
41
  "conformance": "node --disable-warning=ExperimentalWarning conformance/runner.ts"
42
42
  },
43
43
  "dependencies": {
44
- "music-metadata": "^12.0.0",
44
+ "music-metadata": "^12.3.2",
45
45
  "openapi-fetch": "^0.17.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@arethetypeswrong/cli": "0.18.5",
49
49
  "@eslint/js": "10.0.1",
50
- "@stryker-mutator/core": "10.0.0",
51
- "@stryker-mutator/vitest-runner": "10.0.0",
52
- "@types/node": "22.20.5",
53
- "@vitest/coverage-v8": "5.0.3",
54
- "eslint": "10.12.0",
55
- "eslint-plugin-n": "18.4.1",
56
- "eslint-plugin-regexp": "3.3.1",
50
+ "@stryker-mutator/core": "10.1.1",
51
+ "@stryker-mutator/vitest-runner": "10.1.1",
52
+ "@types/node": "24.19.2",
53
+ "@vitest/coverage-v8": "5.0.5",
54
+ "eslint": "10.14.0",
55
+ "eslint-plugin-n": "18.5.0",
56
+ "eslint-plugin-regexp": "3.3.2",
57
57
  "fast-check": "4.10.2",
58
58
  "globals": "17.13.0",
59
- "knip": "6.39.0",
59
+ "knip": "6.44.0",
60
60
  "openapi-typescript": "7.13.0",
61
- "prettier": "3.9.9",
61
+ "prettier": "3.9.10",
62
62
  "publint": "0.3.25",
63
- "tsup": "8.5.1",
63
+ "tsup": "9.0.0",
64
64
  "typescript": "6.0.3",
65
65
  "typescript-floor": "npm:typescript@5.5.4",
66
- "typescript-eslint": "8.71.1",
67
- "vitest": "5.0.3"
66
+ "typescript-eslint": "8.72.1",
67
+ "vitest": "5.0.5"
68
68
  },
69
69
  "overrides": {
70
70
  "openapi-typescript": {
71
71
  "typescript": "$typescript"
72
+ },
73
+ "typed-rest-client": {
74
+ "qs": "6.16.1"
72
75
  }
73
76
  }
74
77
  }