HARMAR API

Բառ առ բառ ժամանակացույցով տրանսկրիպցիա հայերեն խոսքի համար — ներառյալ հայերեն/ռուսերեն/անգլերեն code-switching-ը — ասինխրոն REST API-ով։ Ժամանակավորված բառեր, նախադասություններ, տեքստ, SRT և VTT։ Կամ բաց թող ժամանակացույցը և օգտագործիր որպես հայերեն խոսքից-տեքստ API։

Բանալիներն ու կանխավճարված րոպեները harmar.ai/app/api-ում են։ Առաջին API բանալու հետ՝ 10 րոպե նվեր։

Հիմնական URL:https://api.harmar.ai

Արագ սկիզբ

Ամբողջ հոսքը չորս կանչով՝ ստեղծիր upload, PUT արա ֆայլը, ուղարկիր job-ը, հարցրու արդյունքը։ Job-երն ասինխրոն են — մեկ րոպեանոց վիդեոն սովորաբար պատրաստ է մեկ րոպեից քիչ ժամանակում։

curl
# 1 — create an upload
curl -X POST https://api.harmar.ai/v1/uploads \
-H "Authorization: Bearer hk_live_..." \
-H "Content-Type: application/json" \
-d '{ "filename": "reel.mp4", "file_size": 12345678 }'
 
# 2 — PUT the file to the returned upload_url
curl -X PUT "<upload_url>" \
-H "Content-Type: video/mp4" \
--data-binary @reel.mp4
 
# 3 — submit the job
curl -X POST https://api.harmar.ai/v1/transcripts \
-H "Authorization: Bearer hk_live_..." \
-H "Content-Type: application/json" \
-d '{ "media_id": "<media_id>" }'
 
# 4 — poll the result
curl https://api.harmar.ai/v1/transcripts/<media_id> \
-H "Authorization: Bearer hk_live_..."

Կամ առանց upload-ի. ուղարկիր ֆայլի հանրային հղումը (ուղիղ URL կամ Google Drive / Dropbox-ի share հղում), և job-ը սկսվում է մեկ կանչով։

curl
curl -X POST https://api.harmar.ai/v1/transcripts \
-H "Authorization: Bearer hk_live_..." \
-H "Content-Type: application/json" \
-d '{ "media_url": "https://example.com/reel.mp4", "source_lang": "auto" }'

CLI, MCP և AI ագենտներ

Նույն չորս կանչը՝ փաթեթավորված. harmar-ai npm փաթեթը CLI է սկրիպտների համար և Model Context Protocol server AI ագենտների համար (Claude Code, Claude Desktop, Cursor, Windsurf)։ Դրու HARMAR_API_KEY-ը, և տեղադրում պետք չէ։ Փաթեթի մեջ կա նաև SKILL.md, որն ագենտին սովորեցնում է ամբողջ հոսքը։

shell
export HARMAR_API_KEY=hk_live_...
 
# identify the language, write an SRT
npx -y harmar-ai transcribe reel.mp4 --lang auto --srt --out reel.srt
 
# Russian speech + an Armenian subtitle track, as VTT
npx -y harmar-ai transcribe talk.mp4 --lang ru --translate-to hy --vtt
 
npx -y harmar-ai languages # what --lang accepts, live
npx -y harmar-ai balance # minutes left

Ընդհանրապես առանց terminal-ի. Harmar-ը նաև remote connector է։ claude.ai-ում (կամ Claude Desktop-ում / բջջայինում) բացիր Settings → Connectors → Add custom connector, տեղադրիր ներքևի URL-ը, մուտք գործիր քո Harmar հաշվով, և խնդրիր Claude-ին քո ոճով սուբտիտրեր դնել վիդեոյի վրա։ Աշխատում է քո փաթեթով՝ քո վիդեոները, քո րոպեները, քո պահված ոճերը։

connector URL
https://api.harmar.ai/mcp

Ծրագրավորողների համար՝ նույն գործիքները որպես տեղական MCP server. մեկ տող Claude Code-ի համար, կամ նույնը ցանկացած mcp.json-ում.

shell
claude mcp add harmar -e HARMAR_API_KEY=hk_live_... -- npx -y harmar-ai mcp
mcp.json
{
"mcpServers": {
"harmar": {
"command": "npx",
"args": ["-y", "harmar-ai", "mcp"],
"env": { "HARMAR_API_KEY": "hk_live_..." }
}
}
}

Նույնականացում

Ամեն հարցում կրում է քո գաղտնի բանալին որպես Bearer token։ Բանալին ցույց է տրվում միայն ստեղծման պահին — պահիր server-ում, երբեք client կոդում։ Բանալիները կառավարիր /app/api-ում։

Header
Authorization: Bearer hk_live_...

1 · Ստեղծիր upload

POST/v1/uploads

Վերադարձնում է ստորագրված URL, որին PUT ես անում ֆայլի բայթերը (վավեր է 30 րոպե), և media_id-ն, որն ուղարկելու ես։ Ֆորմատներ՝ MP4, MOV, WebM, M4A, MP3, WAV։ Առավելագույնը՝ 5 ԳԲ, 60 րոպե։

filename
string
պարտադիր
Ֆայլի անունը վերջավորությամբ — որոշում է մեդիայի տեսակը (mp4, mov, webm, m4a, mp3, wav)։
file_size
integer
պարտադիր
Ճշգրիտ չափը բայթերով։ Առավելագույնը՝ 5 ԳԲ։
Հարցում
POST /v1/uploads
{ "filename": "reel.mp4", "file_size": 12345678 }
Պատասխան
{
"media_id": "9b2f7c1e-…",
"upload_url": "https://…r2.cloudflarestorage.com/…", // signed PUT, 30 min
"content_type": "video/mp4",
"expires_in_seconds": 1800
}

Հետո վերբեռնիր բայթերը — Content-Type-ը պիտի ճշգրիտ համընկնի պատասխանում եկածի հետ.

PUT
curl -X PUT "<upload_url>" -H "Content-Type: video/mp4" --data-binary @reel.mp4

2 · Ուղարկիր job-ը

POST/v1/transcripts

Սկսում է job-ը՝ վերբեռնված media_id-ից կամ media_url-ից, որը մենք ենք ներբեռնում (ուղիղ ֆայլի URL կամ Google Drive / Dropbox հղում՝ "anyone with the link" հասանելիությամբ. մինչև 2 ԳԲ. սոցիալական ցանցերի էջերի հղումները չեն ընդունվում)։ Վճարումը մեդիայի ամեն վայրկյանի համար է՝ գանձվում է կանխավճարված մնացորդից սկզբում և ամբողջությամբ վերադարձվում է, եթե job-ը ձախողվի։

Չափված է FLEURS-ով՝ Whisper large-v3-ի դեմ. 57 լեզվում բառային սխալի միջին մակարդակը (WER) 8.1% է՝ 34.5%-ի դիմաց, և ավելի ցածր է 56-ում։ Լեզուները խառնող խոսքում՝ հինդի խոսքի մեջի անգլերեն բառերի վրա 1.3%՝ 54.7%-ի դիմաց. անգլերեն բառը մնում է անգլերեն՝ առանց թարգմանության։ Լեզվի որոշումը («auto») ճիշտ է FLEURS-ի 1,258 հատվածի 94%-ում։ Ամբողջական benchmark-ը՝ harmar.ai/en/blog/whisper-accuracy-benchmark-59-languages

Բոլոր options-ները ձևավորում են նույն մշակման ԱՐԴՅՈՒՆՔԸ — մեկ job, մեկ գին, ցանկացած համադրություն.

media_id
string
POST /v1/uploads-ի վերադարձրած id-ն (PUT-ի ավարտից հետո)։ Ուղարկիր սա կամ media_url-ը։
media_url
string
media_id-ի փոխարեն՝ ֆայլի հանրային հղումը՝ ուղիղ URL կամ Google Drive / Dropbox-ի share հղում ("anyone with the link")։ Մենք ենք այն ներբեռնում (առավելագույնը՝ 2 ԳԲ), upload պետք չէ։ Instagram / TikTok / YouTube էջերի հղումները չեն ընդունվում։
webhook_url
string
HTTPS URL, որին POST ենք անում ավարտին կամ ձախողմանը։ Ստորագրված է — տես Webhook-ներ։
script_text
string
Միայն-ժամանակացույց ռեժիմ. դու տալիս ես ճշգրիտ տեքստը, մենք հաշվում ենք միայն ժամանակները։ Առավելագույնը՝ 100 հազար նիշ։
source_lang
ISO 639-1 code
լռելյայն: "hy"
Ընտրովի դաշտ՝ ինչ լեզվով է մեդիայի խոսքը։ Լռելյայն՝ հայերեն։ Ընդունվում է ցանկացած լեզու GET /v1/languages ցանկից, կամ "auto"՝ լեզուն ձայնից որոշելու համար մինչև տրանսկրիպցիան (պատասխանը վայրկյանների ընթացքում երևում է detected_lang դաշտում)։ Անկախ է translate_to-ից։
keep_media
boolean
լռելյայն: false
Պահել ելակետային մեդիան տրանսկրիպցիայից հետո, որ job-ը հնարավոր լինի export անել որպես վիդեո սուբտիտրերով (տես Վիդեո սուբտիտրերով)։ Լռելյայն անջատած է. պահպանման խոստումն այն է, որ մեդիան ջնջվում է տրանսկրիպտը ստանալուն պես։
translate_to
"ru" | "en" | "hy"
Ընտրովի դաշտ՝ «ru», «en», կամ «hy»։ Թարգմանված սուբտիտրերի track կստանաս բնօրինակի կողքին՝ առանց հավելավճարի (ներառված է րոպեավճարի մեջ)։ Մեկ job՝ մեկ թարգմանության լեզու։
options.timestamps
"word" | "segment" | "none"
լռելյայն: "word"
word → բառ առ բառ + նախադասությունների ժամանակներ; segment → միայն նախադասություններ; none → միայն տեքստ։
options.punctuation
boolean
լռելյայն: true
false-ը հանում է կետադրությունը արդյունքից (3.5 թվերը և ChatGPT-ը ձևերը մնում են անփոփոխ)։
options.speakers
boolean
լռելյայն: true
Խոսողի փոփոխության գծիկներ + speaker id-ներ բառերի վրա։ false-ը հանում է գծիկները; id-ները մնում են։
options.lyrics
"exclude" | "include"
լռելյայն: "exclude"
Երգված տողերը մշակվում են ժամանակների ճշգրտության համար, բայց լռելյայն չեն վերադարձվում; include-ը վերադարձնում է դրանք is_lyric նշումով։
Հարցում
POST /v1/transcripts
{
"media_id": "9b2f7c1e-…",
"webhook_url": "https://yourapp.com/hooks/harmar",
"options": {
"timestamps": "word",
"punctuation": true,
"speakers": true,
"lyrics": "exclude"
}
}
Պատասխան
// 202 Accepted
{
"id": "9b2f7c1e-…",
"status": "processing",
"duration_seconds": 61.4,
"seconds_charged": 62
}

3 · Ստացիր արդյունքը

GET/v1/transcripts/{id}

Հարցրու մինչև status-ը դառնա completed կամ failed (կամ օգտագործիր webhook)։ Ավարտված պատասխանը կրում է տրանսկրիպտը բոլոր միացված ձևերով։

Պատասխան
{
"id": "9b2f7c1e-…",
"status": "completed",
"quality": "ok",
"duration_seconds": 61.4,
"seconds_charged": 62,
"text": "Բարև ձեզ։ ChatGPT-ը լավ tool ա։",
"words": [
{ "text": "Բարև", "start": 0.42, "end": 0.81 },
{ "text": "ChatGPT-ը", "start": 1.02, "end": 1.63, "speaker": 1 }
],
"segments": [
{ "text": "Բարև ձեզ։", "start": 0.42, "end": 0.97 }
],
"srt_url": "/v1/transcripts/9b2f7c1e-…/srt",
"vtt_url": "/v1/transcripts/9b2f7c1e-…/vtt"
}

Պատասխանի դաշտերը

status
"processing" | "completed" | "failed"
Մինչև մեդիայի PUT-ի ավարտը՝ նաև "awaiting_upload"։
progress
integer 0–100
Կա մշակման ընթացքում — իրական պրոգրես, հարմար է progress bar-ի համար։
media_retained
boolean
true, քանի դեռ ելակետային մեդիան պահված է (keep_media job-եր) — export հնարավոր է։
export
{ status }
Կա, երբ export է պահանջվել. "queued" | "rendering" | "completed" | "failed"։ Ամբողջ վիճակը՝ GET /v1/transcripts/{id}/export։
detected_lang
ISO 639-1 code
Կա, երբ source_lang-ը "auto" էր, մշակման առաջին վայրկյաններից — ձայնից որոշված լեզուն։ Երևում է նույնիսկ երբ պատասխանը լռելյայն "hy"-ն է։
quality
"ok" | "degraded"
degraded = որոշ հատվածներում ժամանակային ճշգրտությունը նվազած է; բառերը ճիշտ են։
text
string
Ամբողջ տեքստը՝ մեկ նախադասություն ամեն տողում։
words[]
{ text, start, end, speaker?, is_lyric? }
Բառ առ բառ ժամանակներ վայրկյաններով։ Կա, երբ timestamps = "word"։
segments[]
{ text, start, end, speaker?, is_lyric? }
Նախադասությունների ժամանակներ։ Կա, եթե timestamps ≠ "none"։
srt_url / vtt_url
string
Պատրաստի սուբտիտրի ֆայլերի ուղիներ (նույն Bearer նույնականացումով)։
source_lang
"ru" | "en"
Կա միայն, երբ ոչ-լռելյայն source_lang է պահանջվել ստեղծման պահին (երբեք չի ցուցադրվում լռելյայն «hy»-ի համար)։
translate_to
"ru" | "en" | "hy"
Կա, երբ job-ը թարգմանություն է պահանջել։ Ցույց է տալիս ընտրած լեզուն՝ ցանկացած status-ի վրա, ոչ միայն completed-ի։
translation
{ text, words?, segments? }
«translation» օբյեկտը նույն կառուցվածքն ունի, ինչ հիմնական տրանսկրիպցիան՝ ընտրած լեզվով։ Թարգմանության ձախողումը job-ը չի ձախողում՝ «translation_status: failed» կստանաս, տրանսկրիպցիան կմնա պատրաստ։
translation_status
"failed"
Կա translation-ի փոխարեն, երբ translate_to-ն դրված է, բայց թարգմանությունը չի հաջողվել։ Հազվադեպ է. տրանսկրիպտն ինքնին միևնույն է ավարտվում։
seconds_charged
integer
Ինչ արժեցավ job-ը մնացորդիցդ (= մեդիայի տևողությունը՝ կլորացված վերև)։
error
string
Կա ձախողված job-երի վրա։ Գումարը ավտոմատ վերադարձվում է։

Սուբտիտրի ֆայլեր

GET/v1/transcripts/{id}/srt
GET/v1/transcripts/{id}/vtt

Պատրաստի սուբտիտրի ֆայլեր՝ մեկ cue ամեն նախադասության համար։ Նույն նույնականացումը, տեքստային պատասխաններ.

?lang
ISO 639-1 code
«?lang» պարամետրը բացակայության դեպքում տալիս է սկզբնաղբյուր track-ը (որ լեզվով էլ լինի)։ Կարող ես հստակ նշել source_lang կամ translate_to լեզուն՝ այն track-ը ստանալու համար։
SRT
1
00:00:00,420 --> 00:00:00,970
Բարև ձեզ։
 
2
00:00:01,020 --> 00:00:02,180
ChatGPT-ը լավ tool ա։

Վիդեո սուբտիտրերով (ոճավորված export)

Ոճավորված սուբտիտրերը դրվում են վիդեոյի վրա, և ստանում ես MP4 — առանց լոգոյի, մինչև 1080p, մինչև 60 րոպե։ Տրանսկրիպտը պետք է ուղարկված լինի keep_media: true-ով (լռելյայն ելակետային մեդիան ջնջվում է տրանսկրիպտը ստանալուն պես — տես Տվյալների պահպանում)։ Գանձվում է մեդիայի ամեն վայրկյանի համար՝ տրանսկրիպցիայի գնով, և վերադարձվում է, եթե render-ը ձախողվի։ Մեկ հաշվի համար՝ միաժամանակ մեկ export. հերթում կանգնում է հավելվածի վճարող օգտատերերից հետո։

GET/v1/styles
GET/v1/style-presets
POST/v1/style-presets
DELETE/v1/style-presets/{id}

Ոճը JSON օբյեկտ է — GET /v1/styles-ը տալիս է սուբտիտրի յոթ preset-ը, բոլոր տառատեսակները՝ այն լեզուներով, որոնք իրականում ցուցադրում են, ամեն դաշտը՝ իր միջակայքով, և լռելյայն արժեքները ըստ կողմնորոշման։ Պահիր ոճը մեկ անգամ անունով (POST /v1/style-presets, մինչև 10 հատ) և export արա style_preset_id-ով, որ ամեն վիդեո ստանա ճիշտ նույն տեսքը, կամ ուղարկիր inline՝ style դաշտով։ Անհայտ դաշտը, preset-ը կամ տառատեսակը 400 invalid_style է՝ դաշտի անունով։

curl
# save a style once
curl -X POST https://api.harmar.ai/v1/style-presets \
-H "Authorization: Bearer hk_live_..." \
-H "Content-Type: application/json" \
-d '{ "name": "Brand", "style": { "preset": "pill", "font": "montserrat", "accentColor": "#D4F25A", "posY": 78 } }'
# → 201 { "preset": { "id": "6684e4e5-…", … } }
 
# export a transcript (submitted with keep_media: true) in that style
curl -X POST https://api.harmar.ai/v1/transcripts/<id>/export \
-H "Authorization: Bearer hk_live_..." \
-H "Content-Type: application/json" \
-d '{ "style_preset_id": "6684e4e5-…" }'
# → 202 { "id": "<id>", "export": { "status": "queued", "seconds_charged": 27, "lang": "hy" } }
POST/v1/transcripts/{id}/export
style_preset_id
uuid
Պահված ոճ (POST /v1/style-presets)։ style_preset_id-ից և style-ից ճիշտ մեկը։
style
object
Inline ոճ — GET /v1/styles-ի ցանկացած դաշտ, օրինակ { "preset": "pill", "font": "montserrat", "accentColor": "#D4F25A" }։ Բացակայող դաշտերը վերցնում են կողմնորոշման լռելյայն արժեքները։
lang
ISO 639-1 code
Որ track-ը դնել վիդեոյի վրա. ելակետային լեզուն (լռելյայն) կամ translate_to լեզուն, երբ job-ն ավարտված թարգմանություն ունի։
platform
"instagram" | "youtube" | "tiktok"
Ընտրովի — հարթակի safe-area լռելյայն արժեքները սուբտիտրի դիրքի համար։

Export-ն ասինխրոն է։ Հարցրու GET /v1/transcripts/{id}/export-ը, մինչև status-ը դառնա completed — այդ պատասխանը կրում է ստորագրված download_url, որը վավեր է մեկ ժամ, — կամ failed՝ պատճառով և վերադարձված գումարով։ Webhook-ները ստանում են export.completed / export.failed։

GET/v1/transcripts/{id}/export
status
"queued" | "rendering" | "completed" | "failed"
queued՝ մինչև render-ի slot ազատվի, rendering-ը կրում է progress 0–100։
download_url
url
Երբ completed է — MP4-ի ստորագրված հղում, վավեր download_expires_in_seconds (3600)։ Նորը ստանալու համար նորից կանչիր endpoint-ը։
seconds_charged / seconds_refunded
integer
Գանձումը, իսկ ձախողման դեպքում՝ վերադարձը (միշտ ամբողջ գումարը)։
error
string
failed-ի դեպքում. "render_failed" | "source_missing" | "capacity_exceeded_retry_later" | "superseded"։
JSON
{
"id": "9b2f7c1e-…",
"status": "completed",
"lang": "hy",
"style_preset_id": "6684e4e5-…",
"seconds_charged": 27,
"requested_at": "2026-09-20T13:47:51Z",
"completed_at": "2026-09-20T13:47:59Z",
"size_bytes": 31581412,
"download_url": "https://…/exported.mp4?X-Amz-…",
"download_expires_in_seconds": 3600
}

Պարզ տեքստ

Սուբտիտրե՞ր չես սարքում։ Դիր timestamps-ը "none" — պատասխանը կկրի միայն տեքստը, առանց words ու segments զանգվածների։ Նույն որակը, նույն code-switch մշակումը, նույն գինը։ Հարմար է ձայնային նոթերի, զանգերի տրանսկրիպցիայի, հանդիպումների գրառումների և ձայնով աշխատող հավելվածների համար։

Հարցում
POST /v1/transcripts
{ "media_id": "9b2f7c1e-…", "options": { "timestamps": "none" } }
Պատասխան
{
"id": "9b2f7c1e-…",
"status": "completed",
"text": "Բարև ձեզ։ Այսօր կխոսենք ChatGPT-ի մասին։ Это очень простой tool…"
}

Webhook-ներ

Ուղարկելիս փոխանցիր webhook_url, և ավարտի կամ ձախողման պահին POST կանենք՝ կրկնելով երկու անգամ (30վ և 5ր հետո)։ Job-ը միշտ հասանելի է հարցումով — կորած webhook-ը արդյունք չի կորցնում։

type
"transcript.completed" | "transcript.failed" | "export.completed" | "export.failed"
Իրադարձության տեսակը։
transcript_id
string
Ամբողջ արդյունքը ստացիր GET /v1/transcripts/{id}-ից։
seconds_refunded
integer
Ձախողումների դեպքում — վերադարձված գումարը։
Webhook POST
Harmar-Signature: t=1723000000,v1=5f8a…
 
{
"type": "transcript.completed",
"transcript_id": "9b2f7c1e-…",
"status": "completed",
"duration_seconds": 61.4,
"seconds_charged": 62,
"created_at": "2026-08-07T12:00:00.000Z"
}

Ստուգիր ստորագրությունը՝ HMAC-SHA256 `${t}.${rawBody}`-ից՝ քո բանալու webhook secret-ով (տես /app/api).

Node.js
import { createHmac } from "node:crypto";
 
function verify(signatureHeader, rawBody, webhookSecret) {
const { t, v1 } = Object.fromEntries(
signatureHeader.split(",").map((p) => p.split("="))
);
const expected = createHmac("sha256", webhookSecret)
.update(t + "." + rawBody)
.digest("hex");
return v1 === expected;
}

Սխալներ

Սխալները մեկ ձև ունեն։ HTTP status-ը համընկնում է կոդի հետ.

Պատասխան
// 402
{
"error": {
"code": "insufficient_credits",
"message": "Not enough credits for this media.",
"seconds_needed": 62,
"seconds_available": 14
}
}
invalid_request400Սխալ մուտք — message-ը ասում է, թե որ դաշտը։
unsupported_media400Չաջակցվող ֆորմատ։
duration_limit400Մեդիան գերազանցում է 60 րոպեի սահմանը։
no_audio_track400Մեդիան աուդիո չունի։
media_missing400Submit-ը կանչվել է մինչև upload PUT-ի ավարտը։
media_fetch_failed400/413/422media_url-ը հնարավոր չէ օգտագործել — reason-ը նշում է պատճառը՝ unsupported_link, blocked_host, not_public, not_a_file, unsupported_format, too_large (2 ԳԲ-ից մեծ), fetch_failed։
fetch_busy429Այս հաշվի համար արդեն մի media_url է ներբեռնվում — փորձիր մեկ րոպե անց։
insufficient_credits402Մնացորդը քիչ է — կրում է seconds_needed / seconds_available։
not_found404Անհայտ id (կամ քոնը չէ)։
expired410Տրանսկրիպտն անցել է 30-օրյա պահպանման ժամկետը։
conflict409Job-ի վիճակը թույլ չի տալիս այս կանչը։
invalid_style400Ոճի դաշտ, preset կամ տառատեսակ, որը գոյություն չունի — message-ը նշում է անունը։
media_purged409Export է պահանջվել առանց keep_media ստեղծված տրանսկրիպտի համար — ուղարկիր նորից keep_media: true-ով։
export_in_progress409Այս տրանսկրիպտն արդեն render-վում է։
too_many_exports429Մեկ հաշվի համար՝ միաժամանակ մեկ export։
rate_limit429Չափից շատ հարցումներ — կրում է Retry-After։
  • Ձախողված job-ի գումարն ամբողջությամբ ավտոմատ վերադարձվում է։
  • Խոսք չգտնված job-երը ավարտվում են դատարկ արդյունքով և գանձվում են (աուդիոն մշակվել է)։
  • quality: "degraded"-ը նշում է նվազած ժամանակային ճշգրտություն (ուժեղ երաժշտություն, աղմկոտ աուդիո) — բառերը ճիշտ են, ժամանակները տուժած հատվածներում կարող են մի քանի վայրկյան շեղվել։

Մնացորդ

GET/v1/balance
GET/v1/usage
Պատասխան
GET /v1/balance
{ "seconds_remaining": 28740, "minutes_remaining": 479 }
 
GET /v1/usage
{
"entries": [
{ "kind": "debit", "delta_seconds": -62, "transcript_id": "9b2f…", "created_at": "…" },
{ "kind": "purchase", "delta_seconds": 30000, "created_at": "…" }
],
"credited_seconds": 30600,
"debited_seconds": 62
}

Կանխավճարված րոպեների փաթեթները (500 / 2,000 / 10,000 րոպե) գնվում են /app/api-ում։ Րոպեները ժամկետ չունեն։

Եթե չես ուզում մնացորդին հետևել՝ միացրու ավտոմատ լիցքավորումը /app/api-ում, և երբ մնացորդը իջնի քո ընտրած շեմից, հաշիվը կլիցքավորվի պահված քարտից։ Քարտը պահվում է Stripe-ում, ոչ թե մեզ մոտ — մենք պահում ենք միայն դրա token-ը և վերջին չորս թվանշանները։ Շեմը և փաթեթը ընտրում ես ինքդ, ցանկացած պահի կարող ես անջատել, ինչպես նաև ջնջել պահված քարտը։ Եթե քարտը չանցնի, ավտոմատ լիցքավորումը դադարեցվում է և նամակ է գալիս — կրկնվող փորձեր չեն լինում։ Օրական առավելագույնը 3 ավտոմատ լիցքավորում է։

Գներ

Գները կարդացվում են API-ից, որ քո մարժան հաշվես ծրագրով, ոչ թե էջից պատճենած թվով, որը ժամանակի ընթացքում հնանում է։ Գները ըստ պրոդուկտի են. տրանսկրիպցիան, ժամանակացույցը և rendered captions-ը (ոճավորված export-ը) նշված են առանձին — export-ը արժե նույն րոպեավճարը, ինչ տրանսկրիպտը, որը դրվում է վիդեոյի վրա։

GET/v1/pricing
Պատասխան
{
"currency": "AMD",
"effective_from": "2026-08-08",
"notice_period_days": 30,
"products": {
"transcription": {
"available": true,
"unit": "minute_of_media",
"amd_per_minute": { "from": 25, "to": 40 },
"usd_per_minute": { "from": 0.0687, "to": 0.11 }
},
"timestamps": {
"available": true,
"included_with": "transcription",
"surcharge_amd_per_minute": 0
},
"rendered_captions": { "available": false }
},
"packs": [
{ "id": "starter", "minutes": 500, "price_amd": 20000, "amd_per_minute": 40, "price_usd": 54.99, "usd_per_minute": 0.11 },
{ "id": "growth", "minutes": 2000, "price_amd": 64000, "amd_per_minute": 32, "price_usd": 175.99, "usd_per_minute": 0.088 },
{ "id": "scale", "minutes": 10000, "price_amd": 250000, "amd_per_minute": 25, "price_usd": 686.99, "usd_per_minute": 0.0687 }
],
"trial": { "minutes": 10, "once_per_account": true },
"billing": {
"metered_on": "media_duration",
"unit": "second",
"rounding": "up_to_whole_second",
"charged_before_processing": true,
"refunded_on_failure": true,
"max_media_minutes": 60
}
}

Գների փոփոխությունների մասին գրավոր տեղեկացնում ենք ուժի մեջ մտնելուց առնվազն 30 օր առաջ, իսկ effective_from դաշտը ցույց է տալիս, թե որ գնացուցակն ես կարդում։

Տվյալների պահպանում

Մենք քո օգտատերերի ֆայլերի երկրորդ բազան չենք։ Երկու ժամկետ, երկուսն էլ ավտոմատ.

  • Ելակետային մեդիան (այն, ինչ վերբեռնում ես) ջնջվում է մեր պահոցից տրանսկրիպտը ստանալուն պես։ Ձախողված job-երինը մնում է 24 ժամ՝ պատճառը պարզելու համար, հետո ջնջվում է։ keep_media: true-ով ուղարկված job-ի մեդիան — և render-ված MP4-ը — մնում է վերջին գործողությունից (ստեղծում կամ վերջին export) 24 ժամ, որ export անել հնարավոր լինի։
  • Տրանսկրիպտները հասանելի են ստեղծումից 30 օր, հետո բովանդակությունը ջնջվում է։ Դրանից հետո GET-ը վերադարձնում է 410 expired։
  • Մինչ այդ ցանկացած պահի կարող ես ինքդ ջնջել տրանսկրիպտն ու մեդիան՝ ներքևի endpoint-ով։
DELETE/v1/transcripts/{id}
Պատասխան
{ "id": "9b2f…", "deleted": true, "already_deleted": false }

Idempotent է — արդեն ջնջվածը ջնջելը նորից 200 է վերադարձնում, որ ցանցային խափանումից հետո կրկնելը սխալ չհամարվի։ Դեռ մշակվող job-ը վերադարձնում է 409. ջնջիր ավարտից հետո։ Վճարված job-ի ֆինանսական գրառումը մնում է (առանց քո բովանդակության), որովհետև դա այդ վճարման անդորրագիրն է։

Կապ

Ինտեգրացիա՞ ես սարքում։ Գրիր ciao@harmar.ai — վաղ API գործընկերների հետ աշխատում ենք սերտ։