Hushscript plain REST calls का जवाब भी देता है, उन agents और scripts के लिए जो किसी MCP client चलाने के बजाय सीधे एक HTTP endpoint call करना पसंद करते हैं। पूरे समय यह वही account, वही balance, और वही bearer tokens होते हैं: यहां कुछ भी transcription की price या storage को नहीं बदलता।
Quickstart
API को एक personal access token चाहिए, और इसे पाने के दो तरीक़े हैं। कोई
व्यक्ति account के MCP page पर
Tokens के नीचे एक बनाता है, उसके scopes चुनता है, और तय करता है कि वह
मिनट खरीद सकता है या नहीं। या कोई agent बिना किसी व्यक्ति के अपना ख़ुद का
account खोलता है: POST /v1/agent/accounts एक paid signup शुरू करता है, और
POST /v1/agent/accounts/{signup_id}/claim उसके one-time claim secret को एक
असली account और एक पहले token से exchange करता है। दोनों ही स्थितियों में
token एक बार दिखाया जाता है और hsr1:<region>:pat.<id>.<secret> जैसा दिखता
है। MCP server की OAuth sign-in से mint किया गया token भी यहां काम करता है;
देखें कनेक्ट करें। कोई token कभी दूसरे tokens mint, list, या
revoke नहीं कर सकता, और एक account में ज़्यादा से ज़्यादा 25 active tokens हो
सकते हैं; credential rotation सहित पूरा agent-account flow ऑटोमेटेड
उपयोग walkthrough में है।
एक बार आपके पास token आ जाए, तो सीधे API call करें:
curl https://api.hushscript.com/v1/account \
-H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
{
"balance_seconds": 0,
"held_seconds": 0,
"credits_expire_at": null,
"card_on_file": false,
"data_region": "eu",
"limits": {
"max_active_jobs": 3,
"max_daily_seconds": 36000,
"active_jobs": 0,
"daily_seconds_used": 0
}
}
यह seconds में balance, चल रहे jobs द्वारा held seconds, credit expiry date,
कोई card saved है या नहीं, data region, और admission limits
(max_active_jobs, max_daily_seconds, और अभी तक कितना इस्तेमाल हुआ) बताता
है। कोई नया account शून्य balance से शुरू होता है। POST /v1/uploads card
नहीं, balance जांचता है: बिना मिनटों के यह 3001 insufficient_balance लौटाता
है। Balance वहां तक card के ज़रिए ही पहुंचता है, क्योंकि app में की गई एक बार
की card verification 30 मुफ़्त मिनट release करती है, और packs किसी saved card
के ख़िलाफ़ ख़रीदे जाते हैं।
शुरू से आख़िर तक ऑटोमेट करना
Account के exist करने के बाद सब कुछ बिना किसी व्यक्ति के चलता है, चाहे उस
account को किसी व्यक्ति ने app में खोला हो या किसी agent ने
/v1/agent/accounts के ज़रिए (देखें ऑटोमेटेड उपयोग)। एक अकेला
browser step बचता है, और कोई agent वह browser ख़ुद भी चला सकता है।
-
Account पढ़ें।
GET /v1/account। अगरcard_on_filefalse है, तो पहले एक card save करें। -
एक बार card save करें।
POST /v1/billing/setup-sessionएकcheckout_url, एकsession_id, और एकexpires_atलौटाता है:curl -X POST https://api.hushscript.com/v1/billing/setup-session \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"{ "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8", "session_id": "seti_1PxYzQ2eZvKYlo2C", "expires_at": "2026-09-11T15:45:00Z" }उस URL को अपने नियंत्रण वाले किसी browser में खोलें और hosted Stripe page पूरा करें; कुछ भी charge नहीं होता और Hushscript कभी card नहीं देखता। फिर
GET /v1/billing/cardsउसे उसके id के साथ list करता है। अगर account के पास कई cards हैं, तोPOST /v1/billing/cards/defaultdefault बदल देता है। -
मिनट खरीदें।
GET /v1/billing/packsपांचों packs को उनकेid,seconds,amount, औरcurrencyके साथ list करता है:curl https://api.hushscript.com/v1/billing/packs \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"pack,quick_payment_method_id(saved card का id), और एकidempotency_keyके साथPOST /v1/billing/purchasecard को off-session charge करता है और नयाbalance_secondsबताता है:curl -X POST https://api.hushscript.com/v1/billing/purchase \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \ -H "Content-Type: application/json" \ -d '{ "pack": "300min", "quick_payment_method_id": "pm_2QeT4bY7uX9mK3nP", "idempotency_key": "purchase-2026-09-11-02" }'{ "balance_seconds": 18000 }इसके लिए token पर
billingscope चाहिए और account के लिए billing on होनी चाहिए। बिना card id वाला body, या decline हुआ card,4021 pat_purchase_requires_appके साथ मना कर दिया जाता है; कोई ऐसा card जिसे issuer challenge करना चाहता है,4023 pat_purchase_requires_authenticationके साथ मना कर दिया जाता है। इनमें से कोई भी ऐसा page नहीं खोलता जिसे कोई पूरा न कर सके। -
अपलोड करें।
size_bytes,duration_seconds(15 सेकंड से 10 घंटे तक), एक optionaltitle,transcription_options, और एकidempotency_keyके साथPOST /v1/uploads:curl -X POST https://api.hushscript.com/v1/uploads \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \ -H "Content-Type: application/json" \ -d '{ "size_bytes": 41943040, "duration_seconds": 1200, "title": "Q3 board call", "transcription_options": { "speaker_detection": true }, "idempotency_key": "upload-2026-09-11-02" }'यह एक credit hold लगाता है और एक
job_idके साथ presigned part URLs का पहला page लौटाता है:{ "job_id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8", "part_urls": [ { "n": 1, "url": "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." } ] }हर part को उसके URL पर
PUTकरें (डिफ़ॉल्ट रूप से 32 MiB के parts, आख़िरी वाला छोटा):curl -X PUT "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." \ --data-binary @part-01.binअगले pages
GET /v1/uploads/{job}/part-urls?start=<n>से लें, और किसी लंबे transfer के दौरान 20 मिनट के idle timeout से काफ़ी पहलेPOST /v1/uploads/{job}/heartbeatcall करें। जब presigned URLs उपलब्ध न हों, या कोई एक part fail हो जाए, तोPUT /v1/uploads/{job}/parts/{n}उस part के bytes API के ज़रिए भेज देता है; बार-बार किया गयाPUTउस part की जगह ले लेता है, इसलिए retries सुरक्षित हैं। सिर्फ़ audio: mp3, m4a, wav, flac, ogg, या opus, ज़्यादा से ज़्यादा 5 GB, server पर probe किया जाता है; अपलोड करने से पहले किसी video से audio track निकाल लें। -
शुरू करें और इंतज़ार करें। आपने presigned URL पर जो भी part भेजे हैं, उन सबके
nऔरetagके साथPOST /v1/uploads/{job}/complete(अगर हर part API के ज़रिए गया था, तोpartsछोड़ दें):curl -X POST https://api.hushscript.com/v1/uploads/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8/complete \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \ -H "Content-Type: application/json" \ -d '{ "parts": [ { "n": 1, "etag": "\"9f86d081884c7d65\"" } ] }'फिर
GET /v1/jobs/{id}को poll करें:stateuploading,queued, औरprocessingसे होते हुएdoneयाfailedतक जाता है, और किसी पूरे हो चुके job के साथ एकtranscript_idआता है:curl https://api.hushscript.com/v1/jobs/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8 \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"{ "id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8", "state": "done", "transcript_id": "trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9" } -
नतीजा पढ़ें।
GET /v1/transcripts/{id}metadata और पूरा body लौटाता है, speaker names, detect की गई language, tags, और auto-delete date के साथ:curl https://api.hushscript.com/v1/transcripts/trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9 \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"GET /v1/transcriptslist को pages करता है।
Transcription options वही हैं जो app के हैं, बिल्कुल वैसे ही: language_code
या auto-detection, speaker_detection, medical_mode (language_code को
en, es, fr, या de में होना चाहिए, +100% पर billed),
translation_targets (प्रति भाषा +25%), multichannel, keyterms_prompt,
एक free-text prompt, और वे saved dictionary_ids और prompt_preset_id
जिन्हें GET /v1/transcription-context list करता है।
Account का कुछ हिस्सा अभी भी सिर्फ़ MCP से होकर जाता है। किसी link से import
करना, transcripts edit या delete करना, Insights, exports, dictionaries और
prompt presets save करना, और account settings, इनका अभी कोई /v1/ route
नहीं है; MCP server इन सबको उसी token के साथ cover करता है।
Authentication
हर /v1/ call Authorization header में एक bearer token रखती है, जिसे उन्हीं
scopes के ख़िलाफ़ जांचा जाता है जो MCP server इस्तेमाल करता है:
| Scope | यह क्या allow करता है |
|---|---|
transcripts:read |
Transcripts, उनका metadata, और deleted list पढ़ें और export करें |
transcripts:write |
Transcripts edit, tag, translate, restore, और delete करें |
transcribe |
Recordings अपलोड करें, किसी link से import करें, और transcriptions चलाएं |
insights |
Insights पढ़ें, generate करें, और delete करें |
context |
सेव किए गए शब्दकोश और prompt presets manage करें |
account:read |
Balance, usage, transactions, और holds पढ़ें |
settings:write |
Account settings बदलें |
org:read |
Workspace members, ledger, invoices, और audit log पढ़ें |
export |
पूरे account का export मांगें, उसकी स्थिति जांचें, और उसे download करें |
billing |
सेव किए गए card से minute packs खरीदें |
Token के scopes से बाहर की कोई call pat_scope_missing के साथ 403 पर fail
होती है। billing scope भी तब तक निष्क्रिय रहता है जब तक account owner app
में उस account के लिए billing on नहीं करता; किसी ऐसे account पर billing call
जहां यह switch off है, वही pat_scope_missing देती है, और token को दोबारा
mint करने से यह साफ़ नहीं होता। कोई token tokens बना, list, या revoke नहीं कर
सकता, और एक account में ज़्यादा से ज़्यादा 25 active tokens हो सकते हैं।
Endpoints
आज जो live हैं, हर एक को दिखाए गए scope से gate किया गया है:
| Method | Path | Scope |
|---|---|---|
POST |
/v1/agent/accounts |
none |
POST |
/v1/agent/accounts/{signup_id}/claim |
none |
POST |
/v1/agent/credentials/rotate |
none |
GET |
/v1/account |
account:read |
POST |
/v1/billing/setup-session |
billing |
GET |
/v1/billing/cards |
billing |
POST |
/v1/billing/cards/default |
billing |
GET |
/v1/billing/packs |
billing |
POST |
/v1/billing/purchase |
billing |
GET |
/v1/billing/transactions |
account:read |
GET |
/v1/billing/ledger |
account:read |
GET |
/v1/billing/holds |
account:read |
POST |
/v1/uploads |
transcribe |
GET |
/v1/uploads/{job}/part-urls |
transcribe |
PUT |
/v1/uploads/{job}/parts/{n} |
transcribe |
POST |
/v1/uploads/{job}/heartbeat |
transcribe |
POST |
/v1/uploads/{job}/complete |
transcribe |
GET |
/v1/jobs |
transcribe |
GET |
/v1/jobs/{id} |
transcribe |
GET |
/v1/transcripts |
transcripts:read |
GET |
/v1/transcripts/deleted |
transcripts:read |
GET |
/v1/transcripts/{id} |
transcripts:read |
GET |
/v1/transcription-context |
context |
GET |
/v1/org/members |
org:read |
GET |
/v1/org/invoices |
org:read |
GET |
/v1/org/ledger |
org:read |
GET |
/v1/org/audit |
org:read |
/v1/agent/accounts अभी बिना किसी token के एक headless signup खोलता है,
/v1/agent/accounts/{signup_id}/claim एक paid signup को एक असली account और
उसके पहले token में बदल देता है, और /v1/agent/credentials/rotate calling
token के लिए एक successor mint करता है और उसे revoke कर देता है, account के
किसी और credential को छुए बिना। ऑटोमेटेड उपयोग walkthrough इन
तीनों को शुरू से आख़िर तक cover करता है।
हर list एक limit और एक opaque cursor लेती है, और एक next_cursor लौटाती
है जो आख़िरी page पर null होता है। cursor को बिना बदले वापस भेजें; यह position
encode करता है, इसलिए calls के बीच rows आने पर भी कोई page न तो skip होता है,
न दोहराया जाता है।
हर operation के parameters और response schemas सहित पूरी, मौजूदा definition OpenAPI document में है: इसे इस table से ऊपर source of truth मानें। यह किसी भी bearer token को scope की परवाह किए बिना दिया जाता है, इसलिए कोई client इसे अपने पास पहले से मौजूद credentials के साथ ही fetch कर सकता है।
MCP interface
raw HTTP के बजाय tools पसंद करते हैं? MCP server उस client के लिए, जो REST के बजाय पहले से MCP बोलता है, इन्हीं endpoints की जगह उसी account को 51 tools के पीछे रखता है।
Limits
किसी token से की गई requests प्रति token प्रति मिनट 1,200 तक सीमित हैं।
POST /v1/billing/setup-session और POST /v1/billing/purchase उस Stripe
call से पहले, जो ये करने वाले होते हैं, प्रति account प्रति मिनट 60 का एक
ज़्यादा tight budget share करते हैं। कोई मना की गई request Retry-After
header के साथ 429 rate_limited लौटाती है, जो सेकंड में इंतज़ार का समय
बताता है; retry करने से पहले उतनी देर रुकें। Uploads 5 GB और 10 घंटे पर
capped हैं, 15 सेकंड के minimum के साथ, और account की अपनी admission limits
(max_active_jobs, max_daily_seconds) GET /v1/account से मिलती हैं।
Sandbox
कोई dry-run mode नहीं है: हर /v1/ call एक असली account के ख़िलाफ़ चलती है,
और मिनट खरीदने पर असली पैसे ख़र्च होते हैं।
Errors
कोई error एक JSON body होती है जिसमें नीचे दिए गए HTTP status पर एक स्थिर
numeric code और एक error slug होता है। /v1/ error bodies एक frozen
projection हैं: error, code, और detail keys का एक तय सेट। /api का error
shape frozen नहीं है और इसमें ज़्यादा चीज़ें हो सकती हैं। वे codes जिन्हें
किसी automated caller को handle करना चाहिए:
| Status | Code | Slug | अर्थ |
|---|---|---|---|
| 401 | 2000 | unauthorized |
Bearer token missing या invalid है |
| 403 | 2022 | pat_forbidden |
यह route बिलकुल कोई token accept नहीं करता |
| 403 | 2023 | pat_scope_missing |
Token के पास इस call के लिए ज़रूरी scope नहीं है, या account के लिए billing off है |
| 403 | 4021 | pat_purchase_requires_app |
कोई saved card नहीं बताया गया था, या charge decline हो गया; कुछ भी charge नहीं हुआ |
| 403 | 4023 | pat_purchase_requires_authentication |
Card issuer एक ऐसा challenge चाहता है जो caller पूरा नहीं कर सकता; card खुद ठीक है |
| 402 | 3001 | insufficient_balance |
Job को admit करने के लिए पर्याप्त balance नहीं है |
| 402 | 3002 | card_declined |
Saved card decline हो गया |
| 402 | 3003 | org_insufficient_balance |
इस upload को fund करने वाला workspace pool कम पड़ रहा है |
| 404 | 4000 | not_found |
ऐसा कोई job, upload, या resource नहीं है |
| 409 | 4001 | wrong_state |
Resource ऐसी state में नहीं है जो इसकी अनुमति दे |
| 422 | 1021 | duration_out_of_range |
बताई गई duration 15 सेकंड से कम या 10 घंटे से ज़्यादा है |
| 429 | 5000 | rate_limited |
बहुत ज़्यादा requests; Retry-After का इंतज़ार करें |
| 502 | 6001 | provider_error |
कोई upstream service fail हो गई |
| 500 | 9000 | internal_error |
कोई अनपेक्षित server error |
OpenAPI document हर operation के लौटा सकने वाले exact code बताता है, और MCP
server पूरा catalog hushscript://error-codes resource के रूप में publish
करता है।