@hushscript/sdk 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/index.d.ts +32 -22
- package/dist/index.js +21 -13
- package/package.json +12 -12
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
100
|
-
* @description Returns the caller's net credit balance,
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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,
|
|
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.
|
|
12
|
+
version: "1.1.0"};
|
|
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: "
|
|
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
|
|
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),
|
|
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
|
|
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: "
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
3
|
+
"version": "1.1.0",
|
|
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": ">=
|
|
16
|
+
"node": ">=24"
|
|
17
17
|
},
|
|
18
18
|
"sideEffects": false,
|
|
19
19
|
"files": [
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"conformance": "node --disable-warning=ExperimentalWarning conformance/runner.ts"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"music-metadata": "^12.
|
|
44
|
+
"music-metadata": "^12.2.3",
|
|
45
45
|
"openapi-fetch": "^0.17.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
@@ -49,22 +49,22 @@
|
|
|
49
49
|
"@eslint/js": "10.0.1",
|
|
50
50
|
"@stryker-mutator/core": "10.0.0",
|
|
51
51
|
"@stryker-mutator/vitest-runner": "10.0.0",
|
|
52
|
-
"@types/node": "
|
|
53
|
-
"@vitest/coverage-v8": "5.0.
|
|
54
|
-
"eslint": "10.
|
|
55
|
-
"eslint-plugin-n": "18.
|
|
52
|
+
"@types/node": "24.19.2",
|
|
53
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
54
|
+
"eslint": "10.13.0",
|
|
55
|
+
"eslint-plugin-n": "18.5.0",
|
|
56
56
|
"eslint-plugin-regexp": "3.3.1",
|
|
57
57
|
"fast-check": "4.10.2",
|
|
58
58
|
"globals": "17.13.0",
|
|
59
|
-
"knip": "6.
|
|
59
|
+
"knip": "6.42.1",
|
|
60
60
|
"openapi-typescript": "7.13.0",
|
|
61
|
-
"prettier": "3.9.
|
|
61
|
+
"prettier": "3.9.10",
|
|
62
62
|
"publint": "0.3.25",
|
|
63
|
-
"tsup": "
|
|
63
|
+
"tsup": "9.0.0",
|
|
64
64
|
"typescript": "6.0.3",
|
|
65
65
|
"typescript-floor": "npm:typescript@5.5.4",
|
|
66
|
-
"typescript-eslint": "8.
|
|
67
|
-
"vitest": "5.0.
|
|
66
|
+
"typescript-eslint": "8.72.0",
|
|
67
|
+
"vitest": "5.0.5"
|
|
68
68
|
},
|
|
69
69
|
"overrides": {
|
|
70
70
|
"openapi-typescript": {
|