REST API
גישת API להתממשקות ישירה למערכת או תוכנה. תכונות נוספות יתווספו עם הזמן.
כתובת בסיסית ואימות
כל נקודות הקצה הציבוריות נמצאות תחת https://aicall.co.il/api/v1. האימות הוא כותרת Bearer בודדת — ללא עוגיות, ללא סודות בכתובת ה-URL וללא תהליכי OAuth.
- תמיד יש לשלוח
Authorization: Bearer <key>. כותרת חסרה או שגויה תחזיר401עם הודעת שגיאה מתורגמת. - אסימוני משתמש מונפקים מ-
/dashboard/developers/api-keys, ואסימוני אדמין מ-/admin/api-keys. כולם מתחילים בקידומתak_live_…. - המפתח המלא מוצג פעם אחת בלבד ביצירה. אם המפתח אבד — יש לבטל אותו ולהנפיק חדש; אין אפשרות לשחזר.
- לכל מפתח מוגדרות הרשאות (scopes) ביצירה. קריאה לנקודת קצה שאינה מכוסה תחזיר
INSUFFICIENT_SCOPEולא 401. - מומלץ להתייחס למפתחות כמו לסיסמאות: לשמור במשתני סביבה, להחליף מעת לעת ולהגדיר רשימת היתרים של IP במידת האפשר.
curl https://aicall.co.il/api/v1/profile \
-H "Authorization: Bearer ak_live_xyz9aBcdef..."מבנה תשובה סטנדרטי
כל נקודת קצה — הצלחה או שגיאה — מחזירה את אותו מעטפת. כדאי להסתעף לפי השדה ok, ולא לסמוך רק על קוד ה-HTTP.
- הצלחה —
{ ok: true, data: …, requestId }. אובייקטdataשונה לכל נקודת קצה;requestIdמאפשר תיאום בין הלוג שלך לבין הטרייסים בצד השרת. - שגיאה —
{ ok: false, error: { code, message, messageEn, details? }, requestId }. השדהcodeהוא מזהה יציב שמיועד להסתעפות בקוד (ראו את בלוק השגיאות בהמשך). - תרגום —
messageנקבע לפי כותרתAccept-Language, או לפי שפת ברירת המחדל של החשבון אם הכותרת לא נשלחה. - טקסט קבוע באנגלית —
messageEnנשמר תמיד באנגלית ללא קשר לשפת התגובה, כדי שדשבורדים תפעוליים וכלי לוגים יישארו עקביים. - פירוט מובנה — כשרלוונטי, השדה
detailsכולל מידע פעולתי (לדוגמה{ requiredUsd, balanceUsd }בשגיאת יתרה לא מספיקה).
{
"ok": true,
"data": {
"id": "user_abc",
"email": "you@example.com",
"balance": { "amount_usd": 12.34 }
},
"requestId": "req_4f1b2a3d"
}{
"ok": false,
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Your account balance is too low for this request.",
"messageEn": "Your account balance is too low for this request.",
"details": { "requiredUsd": 0.12, "balanceUsd": 0.04 }
},
"requestId": "req_4f1b2a3d"
}התאמת חיוב
ה-API והדשבורד חולקים ספר חשבונות אחד, קובץ תמחור אחד ומגבלות מקבילות זהות. אין תוספת חיוב על קריאות API.
- תמלול מחייב דרך אותו מסלול
priceTranscribe()שבו הדשבורד משתמש — אותו תעריף לדקה, אותו חישוב מטבע. - כתוביות מחייב את כל השלבים הפעילים: ניקוי האודיו (כשמסומן
use_voice_cleanup) ושלב הצריבה. שני החיובים מופיעים בעמוד השימוש של המשתמש. - מקבילות — תקרות לכל משתמש ולכלל הפלטפורמה מוגדרות ב-
app_settingsוחלות על שני הממשקים. שליחת יותר מדי משימות במקביל תחזירTOO_MANY_JOBS. - צריבה מחדש חינמית — לאחר שמשימת כתוביות עובדה, קריאה ל-
POST /subtitles/{id}/reburnתפעיל מחדש רק את שלב ffmpeg על בסיס ה-SRT השמור; אין חיוב נוסף על תמלול או ניקוי אודיו. - התראות פועלות לפי הגדרות החשבון (PWA push, ובאופציה גם דוא״ל ו-SMS). משימות API מקבלות push בלבד כברירת מחדל — להוסיף דוא״ל/SMS לכל קריאה דרך השדות
email_after/sms_after.
{
"id": 91,
"service": "speech-to-text",
"status": "done",
"audio_duration_sec": 360,
"cost_usd": "0.0240",
"source": "api",
"created_at": "2026-05-22T07:30:00Z",
"completed_at": "2026-05-22T07:32:48Z"
}לוג עבודות
שתי נקודות הקצה של הרשימות מספקות תצוגה מתגלגלת של המשימות האחרונות. שימושיות לסקירת השלמה או להשוואה מול מטמון מקומי.
GET /api/v1/transcribe— עד 50 משימות תמלול אחרונות, חדשות תחילה. כולל שם קובץ, שפה מזוהה, סטטוס, תמונת עלות, ומקור (uiמולapi).GET /api/v1/subtitles— עד 50 משימות כתוביות אחרונות עם כתובת פלט הצריבה, דגל ניקוי אודיו ועלות פר-שלב.- שורות שנמחקו רכות מוסננות אוטומטית. גם הדשבורד מסתיר אותן, אבל תנועות הקרדיט המקוריות נשמרות.
- צריך היסטוריה עמוקה או ייצוא בכמויות?
/docs/data-exportsב-roadmap — בינתיים אפשר לפנות לתמיכה ונפיק קובץ JSONL מותאם.
{
"ok": true,
"data": {
"jobs": [
{
"id": 91,
"status": "done",
"file_name": "interview.mp3",
"audio_duration_sec": 360,
"cost_usd": "0.0240",
"language": { "detected": "en" },
"source": "api",
"created_at": "2026-05-22T07:30:00Z"
},
{
"id": 92,
"status": "queued",
"file_name": "demo.mp4",
"source": "api",
"created_at": "2026-05-22T07:55:11Z"
}
]
},
"requestId": "req_abc"
}שגיאות שתפגוש בדרך
כדאי להסתעף בקוד לפי המחרוזת error.code — היא יציבה ולא משתנה ללא מעבר לגרסה ראשית חדשה. הקודים השכיחים:
UNAUTHORIZED— אין כותרתAuthorizationכלל.INVALID_API_KEY— המפתח בוטל, פג, או שה-hash לא תואם. יש להנפיק מפתח חדש מהדשבורד.INSUFFICIENT_SCOPE— המפתח תקף אבל חסרה לו ההרשאה הנדרשת לנקודת הקצה (לדוגמה קריאה ל-transcribe:writeעם מפתח קריאה בלבד).RATE_LIMITED— מגבלת קצב למפתח. בתגובה תוחזר כותרתRetry-Afterשכדאי לכבד.TOO_MANY_JOBS— מגבלת מקבילות למשתמש. כדאי להמתין לסיום משימות פעילות; המגבלה ניתנת לכוונון על-ידי האדמין.INSUFFICIENT_BALANCE— אפשר לטעון מחדש ב-/dashboard/billing. השדהdetailsמציג את הסכום הנדרש מול היתרה הקיימת.FILE_TOO_LARGE— העלאות עד 500 MB. כדאי לחלק מדיה ארוכה לפני השליחה.NO_AUDIO_STREAM— לסרטון אין רצועת אודיו (נפוץ בהקלטות מסך שקטות). יש לקודד מחדש עם ערוץ אודיו לפני השליחה.VOICE_API_NOT_CONFIGURED— האדמין עדיין לא חיבר את שירות הקול. אפשר לפנות אלינו ונסדר את זה בצד שלנו.
{
"ok": false,
"error": {
"code": "TOO_MANY_JOBS",
"message": "Per-user concurrency limit reached (5/5).",
"messageEn": "Per-user concurrency limit reached (5/5).",
"details": { "inFlight": 5, "limit": 5 }
},
"requestId": "req_b8e7c2"
}תיעוד REST API
v1כתובת בסיס יחידה, אימות באמצעות Bearer, ואותה גביית קרדיט שיש בדשבורד. כל נקודת קצה מתועדת עם טבלת פרמטרים, קודי תגובה, דוגמאות קוד וכלי ניסוי בדפדפן.
ok=true ואובייקט data שמותאם לנקודת הקצה.
{
"ok": true,
"data": { /* endpoint-specific payload */ },
"requestId": "req_4f1b2a3d"
}ok=false עם קוד יציב ועם הודעה ידידותית בשפת המבקש.
{
"ok": false,
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Your account balance is too low for this request.",
"messageEn": "Your account balance is too low for this request.",
"details": { "requiredUsd": 0.12, "balanceUsd": 0.04 }
},
"requestId": "req_4f1b2a3d"
}התחלה מהירה
קריאה לפרופיל בשלוש שורות. יש להחליף את API_KEY בסוד שהוחזר מ-/api/v1/keys.
curl https://aicall.co.il/api/v1/profile \
-H "Authorization: Bearer $API_KEY"import os, requests
response = requests.get(
"https://aicall.co.il/api/v1/profile",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://aicall.co.il/api/v1/profile", {
headers: { "Authorization": `Bearer ${process.env.API_KEY}` },
});
const profile = await response.json();
console.log(profile);תיעוד REST API
/api/v1/healthבריאות השירות (ללא אימות)
בדיקת זמינות קלת משקל לשימוש כלי ניטור.
- מחזיר 200 כאשר היישום ובסיס הנתונים פעילים.
- בטוח לסקור בכל קצב — אין צורך באימות.
- הגרסה המעמיקה (
?deep=true) למפתחות אדמין בלבד וחושפת זמני תגובה של ספקים.
בקשה
curl -X GET https://aicall.co.il/api/v1/health \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"status": "healthy",
"time": "2026-05-22T08:00:00Z",
"version": "1.2.5",
"uptimeSec": 1234
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/healthבקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"status": "healthy",
"time": "2026-05-22T08:00:00Z",
"version": "1.2.5",
"uptimeSec": 1234
},
"requestId": "req_abc"
}/api/v1/keysרשימת מפתחות ה-API שלך
מחזיר את כל המפתחות של מבקש הקריאה (או את כולם כאשר נקרא עם מפתח אדמין).
- הסוד המלא לעולם לא נחשף — רק קידומת מוסתרת.
- גם מפתחות שבוטלו או פגו מופיעים, עם חותמות הזמן של
revoked_at/expires_at. - שימוש מצוין למעקב אחר אילו מפתחות בשימוש ומתי נראו לאחרונה.
בקשה
curl -X GET https://aicall.co.il/api/v1/keys \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": [
{
"id": 1,
"name": "Production server",
"prefix": "ak_live_abc123…",
"owner_type": "user",
"scopes": [
"profile:read",
"transcribe:write"
],
"tier": "default",
"expires_at": "2027-01-01T00:00:00Z",
"last_used_at": "2026-05-22T07:55:11Z",
"revoked_at": null,
"created_at": "2026-04-01T00:00:00Z"
}
],
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/keysדורש את ההרשאה keys:manage.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": [
{
"id": 1,
"name": "Production server",
"prefix": "ak_live_abc123…",
"owner_type": "user",
"scopes": [
"profile:read",
"transcribe:write"
],
"tier": "default",
"expires_at": "2027-01-01T00:00:00Z",
"last_used_at": "2026-05-22T07:55:11Z",
"revoked_at": null,
"created_at": "2026-04-01T00:00:00Z"
}
],
"requestId": "req_abc"
}/api/v1/keysיצירת מפתח API חדש
יוצר מפתח חדש ומחזיר את הסוד המלא פעם אחת בלבד.
- מפתחות משתמש חייבים לפוג תוך 365 ימים; מפתחות אדמין יכולים להיות ללא תוקף.
- ה-Scope מאומת מול רמת המבקש — Scope אדמין נדחה במפתחות משתמש.
- חובה לשמור את הסוד מיד — הוא לא יוצג שוב, רק קידומת מוסתרת.
גוף הבקשה
{
"name": "API Docs Test Key",
"scopes": [
"profile:read",
"transcribe:read",
"transcribe:write"
],
"expires_at": "2027-01-01T00:00:00Z"
}בקשה
curl -X POST https://aicall.co.il/api/v1/keys \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"API Docs Test Key","scopes":["profile:read","transcribe:read","transcribe:write"],"expires_at":"2027-01-01T00:00:00Z"}'תגובה
{
"ok": true,
"data": {
"id": 42,
"name": "API Docs Test Key",
"prefix": "ak_live_xyz9…",
"secret": "ak_live_xyz9aBcdef_…shown_once_only…",
"scopes": [
"profile:read",
"transcribe:read",
"transcribe:write"
],
"owner_type": "user",
"tier": "default",
"expires_at": "2027-01-01T00:00:00Z",
"created_at": "2026-05-22T08:00:00Z",
"warning": "Store this secret securely — it will not be shown again."
},
"requestId": "req_abc"
}תגובות
- 201הצלחה
- 400Scope לא חוקי או תוקף מעל 365 ימים.
ניסוי
/api/v1/keysדורש את ההרשאה keys:manage.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 42,
"name": "API Docs Test Key",
"prefix": "ak_live_xyz9…",
"secret": "ak_live_xyz9aBcdef_…shown_once_only…",
"scopes": [
"profile:read",
"transcribe:read",
"transcribe:write"
],
"owner_type": "user",
"tier": "default",
"expires_at": "2027-01-01T00:00:00Z",
"created_at": "2026-05-22T08:00:00Z",
"warning": "Store this secret securely — it will not be shown again."
},
"requestId": "req_abc"
}/api/v1/transcribeרשימת משימות התמלול שלך
מחזיר את משימות התמלול האחרונות, חדשות תחילה.
- כולל פרטי קובץ, שפה מזוהה ותמונת מצב של עלות לכל משימה.
- שדה
statusמשקף את מצב הצינור:queued·processing·done·failed. - לקבלת חותמות זמן ברמת מילה יש לפנות לנקודת הקצה של המשימה הבודדת.
בקשה
curl -X GET https://aicall.co.il/api/v1/transcribe \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"jobs": [
{
"id": 91,
"service": "speech-to-text",
"status": "done",
"kind": "file",
"file_name": "interview.mp3",
"audio_duration_sec": 360,
"transcript_text": "We started by going over the proposal …",
"cost_usd": "0.0240",
"language": {
"detected": "en"
},
"source": "api",
"created_at": "2026-05-22T07:30:00Z",
"completed_at": "2026-05-22T07:32:48Z"
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/transcribeדורש את ההרשאה transcribe:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"jobs": [
{
"id": 91,
"service": "speech-to-text",
"status": "done",
"kind": "file",
"file_name": "interview.mp3",
"audio_duration_sec": 360,
"transcript_text": "We started by going over the proposal …",
"cost_usd": "0.0240",
"language": {
"detected": "en"
},
"source": "api",
"created_at": "2026-05-22T07:30:00Z",
"completed_at": "2026-05-22T07:32:48Z"
}
]
},
"requestId": "req_abc"
}/api/v1/transcribe/{id}שליפת תמלול בודד
מחזיר את התמלול המלא, כולל חותמות זמן ברמת מילה, ברגע שהמשימה מסומנת done.
- בזמן
queuedאוprocessingשדהtranscript_textריק ושדהwordsמושמט. - השדה
language.detectedמחזיק קוד שפה שזוהה אוטומטית (לדוגמהen,he). - במשימות שכשלו מופיעים שדות
error_codeו-error_messageשמתארים את הסיבה.
פרמטרים
idpathstringחובהמזהה המשימה מתשובת היצירה.
בקשה
curl -X GET https://aicall.co.il/api/v1/transcribe/id \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"id": 91,
"service": "speech-to-text",
"status": "done",
"transcript_text": "…",
"words": [
{
"word": "We",
"start": 0,
"end": 0.1
}
],
"language": {
"detected": "en"
}
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/transcribe/{id}דורש את ההרשאה transcribe:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 91,
"service": "speech-to-text",
"status": "done",
"transcript_text": "…",
"words": [
{
"word": "We",
"start": 0,
"end": 0.1
}
],
"language": {
"detected": "en"
}
},
"requestId": "req_abc"
}/api/v1/transcribe/{id}/exportהורדת תמלול
מחזיר את התמלול בפורמט המבוקש.
txt— טקסט נקי, פסקה לכל דובר.md— Markdown עם כותרות לפי דובר.srt— קובץ קיוז בפורמט SubRip לנגני וידאו.json— payload מובנה מלא עם חותמות זמן לכל מילה.
פרמטרים
idpathstringחובהformatquerystringאופציונליtxt / md / srt / json · ברירת מחדל: txt
בקשה
curl -X GET https://aicall.co.il/api/v1/transcribe/id/export?format=txt \
-H "Authorization: Bearer $API_KEY"תגובה
We started by going over the proposal — let me know if you have questions…תגובות
- 200הצלחה
ניסוי
/api/v1/transcribe/{id}/exportדורש את ההרשאה transcribe:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
We started by going over the proposal — let me know if you have questions…/api/v1/subtitlesרשימת משימות כתוביות
מחזיר את משימות הכתוביות האחרונות עם פרטי עלות וקישור לסרטון הצרוב.
- בכל שורה מצוין דגל ניקוי אודיו, עלות הצריבה ומשך הסרטון המקורי.
- הכתובת
output_video_urlחתומה ועוברת דרך הדומיין שלנו — ללא חשיפת ספק. - להורדת קובץ
.srtיש להשתמש בנקודת הקצה הייעודית.
בקשה
curl -X GET https://aicall.co.il/api/v1/subtitles \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"jobs": [
{
"id": 7,
"service": "subtitles",
"status": "done",
"file_name": "talk.mp4",
"video_duration_sec": 320,
"output_video_url": "/api/uploads/uploads/subtitles/user_abc/…-burned.mp4",
"used_voice_cleanup": true,
"voice_cleanup_cost_usd": "0.0780",
"burn_cost_usd": "0.0032"
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/subtitlesדורש את ההרשאה subtitles:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"jobs": [
{
"id": 7,
"service": "subtitles",
"status": "done",
"file_name": "talk.mp4",
"video_duration_sec": 320,
"output_video_url": "/api/uploads/uploads/subtitles/user_abc/…-burned.mp4",
"used_voice_cleanup": true,
"voice_cleanup_cost_usd": "0.0780",
"burn_cost_usd": "0.0032"
}
]
},
"requestId": "req_abc"
}/api/v1/subtitles/{id}/srtהורדת קובץ SRT
מחזיר את ה-SRT הנוכחי של משימה שהושלמה כטקסט UTF-8 נקי.
- כולל עריכות שנשמרו דרך עורך הדשבורד או נשלחו דרך נקודת הקצה PUT.
- הפלט הזה הוא מקור האמת לצריבה מחדש — ראו את נקודת הקצה הבאה.
- סוג התגובה הוא
text/plain, לא JSON, כך שהגוף הוא SRT גולמי.
פרמטרים
idpathstringחובהבקשה
curl -X GET https://aicall.co.il/api/v1/subtitles/id/srt \
-H "Authorization: Bearer $API_KEY"תגובה
1
00:00:01,000 --> 00:00:03,500
Hello there!
תגובות
- 200הצלחה
ניסוי
/api/v1/subtitles/{id}/srtדורש את ההרשאה subtitles:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
1
00:00:01,000 --> 00:00:03,500
Hello there!
/api/v1/subtitles/{id}/reburnצריבה מחדש לאחר עריכת SRT (חינם)
מריץ מחדש את שלב הצריבה לפי ה-SRT הנוכחי.
- ללא חיוב על תמלול או ניקוי אודיו — רק ffmpeg מורץ.
- שימושי כשטקסט הכתוביות נערך וצריך לרענן את התצוגה בסרטון.
- הכתובת של פלט הצריבה מתעדכנת בשורת המשימה כשהריצה מסתיימת.
פרמטרים
idpathstringחובהבקשה
curl -X POST https://aicall.co.il/api/v1/subtitles/id/reburn \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"id": 7,
"reburned": true
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/subtitles/{id}/reburnדורש את ההרשאה subtitles:write.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 7,
"reburned": true
},
"requestId": "req_abc"
}/api/v1/smsשליחת SMS — בודד או אצווה
נקודת קצה אחת לשליחה בודדת ולאצווה. recipients תמיד מערך — ערך אחד מחזיר תשובה סינכרונית, יותר מאחד מכניס לתור ומחזיר 202 עם jobId.
- שדה
fromחייב להיות מספר שיש עליו בעלות (אפשר לרכוש ב-/dashboard/agents). - שדה
bodyהוא תבנית — שדות{{key}}מוחלפים מאובייקטvariablesשל כל נמען. שדה חסר חוסם את כל האצווה לפני שליחה. - עברית / ערבית מעבירות אוטומטית לקידוד UCS-2 (כ-70 תווים למקטע במקום 160 ב-GSM-7); התמחור לפי מקטעים.
- אימות מספר טלפון לחשבון נדרש קודם — חשבון לא מאומת מקבל
412 SMS_PHONE_NOT_VERIFIED. - מכסות יומיות: משתמשים חינמיים 5 ביום + יתרה חיובית; משתמשים בתשלום 200/יום ל-US, 100/יום לישראל (ניתן לכיוון על ידי האדמין).
גוף הבקשה
{
"from": "+972501111111",
"body": "Hi {{name}}, your link is {{link}}",
"recipients": [
{
"phone": "+972502222222",
"variables": {
"name": "Dana",
"link": "https://example.com/d"
}
},
{
"phone": "+972503333333",
"variables": {
"name": "Avi",
"link": "https://example.com/a"
}
}
]
}בקשה
curl -X POST https://aicall.co.il/api/v1/sms \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"+972501111111","body":"Hi {{name}}, your link is {{link}}","recipients":[{"phone":"+972502222222","variables":{"name":"Dana","link":"https://example.com/d"}},{"phone":"+972503333333","variables":{"name":"Avi","link":"https://example.com/a"}}]}'תגובה
{
"ok": true,
"data": {
"jobId": 17,
"recipientCount": 2,
"estimatedCostUsd": 0.0822,
"estimatedPriceUsd": 0.0944,
"perCountry": {
"IL": 2
}
},
"requestId": "req_abc"
}תגובות
- 202הצלחה
- 400חסר שדה דינמי לאחד הנמענים.
- 402אין מספיק קרדיט בחשבון.
- 403מדינת היעד לא ברשימה המאופשרת.
- 412אימות מספר טלפון לפני שליחת SMS.
- 413האצווה חורגת ממספר הנמענים המרבי.
- 429נגמרה המכסה היומית של SMS.
ניסוי
/api/v1/smsדורש את ההרשאה sms:send.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"jobId": 17,
"recipientCount": 2,
"estimatedCostUsd": 0.0822,
"estimatedPriceUsd": 0.0944,
"perCountry": {
"IL": 2
}
},
"requestId": "req_abc"
}/api/v1/sms/jobs/{id}בדיקת אצוות SMS
מחזיר את המצב הנוכחי של האצווה ורשימת תוצאות לכל נמען.
- מעברי
status:queued → processing → completed(אוpartialאם חלק נכשלו,failedאם כולם). - שורת נמען מכילה
statusמסירה, מספר מקטעים, קידוד ועלות להודעה. בכישלון מצורפיםerrorCodeו-errorMessage. - קצב פולינג מומלץ: 2 שניות. cron השלמה ב-
/api/cron/refresh-sms-statusמעדכן את המצב כל 5 דקות במקרה ש-callback של מסירה התפספס.
פרמטרים
idpathnumberחובהמזהה האצווה שמוחזר מ-POST /api/v1/sms.
בקשה
curl -X GET https://aicall.co.il/api/v1/sms/jobs/id \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"id": 17,
"status": "completed",
"totalRecipients": 2,
"sentCount": 2,
"failedCount": 0,
"totalCostUsd": 0.0822,
"totalPriceUsd": 0.0944,
"startedAt": "2026-05-27T10:00:01Z",
"completedAt": "2026-05-27T10:00:03Z",
"recipients": [
{
"id": 1042,
"body": "Hi Dana, your link is https://example.com/d",
"segments": 1,
"encoding": "gsm7",
"status": "delivered",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0.0472,
"costUsd": 0.0411
},
{
"id": 1043,
"body": "Hi Avi, your link is https://example.com/a",
"segments": 1,
"encoding": "gsm7",
"status": "delivered",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0.0472,
"costUsd": 0.0411
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
- 404האצווה לא נמצאה או לא שייכת לחשבון שלך.
ניסוי
/api/v1/sms/jobs/{id}דורש את ההרשאה sms:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 17,
"status": "completed",
"totalRecipients": 2,
"sentCount": 2,
"failedCount": 0,
"totalCostUsd": 0.0822,
"totalPriceUsd": 0.0944,
"startedAt": "2026-05-27T10:00:01Z",
"completedAt": "2026-05-27T10:00:03Z",
"recipients": [
{
"id": 1042,
"body": "Hi Dana, your link is https://example.com/d",
"segments": 1,
"encoding": "gsm7",
"status": "delivered",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0.0472,
"costUsd": 0.0411
},
{
"id": 1043,
"body": "Hi Avi, your link is https://example.com/a",
"segments": 1,
"encoding": "gsm7",
"status": "delivered",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0.0472,
"costUsd": 0.0411
}
]
},
"requestId": "req_abc"
}/api/v1/sms/threadsרשימת שיחות SMS
שיחה אחת לכל זוג (מספר שלך, מספר הצד השני), ממוין לפי פעילות אחרונה.
- כל שיחה מציגה את המספר שלך, את הצד השני, מונה הודעות לא נקראות וזמן ההודעה האחרונה.
- שיחות בארכיון מוסתרות — הן חוזרות אוטומטית בהודעה הבאה מהצד השני.
- אפשר לסנן למספר אחד דרך
?ownedNumberId=42.
פרמטרים
limitquerynumberאופציונלימספר השיחות המקסימלי להחזרה (1–200). · ברירת מחדל: 50
offsetquerynumberאופציונליOffset לדפדוף. · ברירת מחדל: 0
ownedNumberIdquerynumberאופציונליסינון לפי מספר שיש עליו בעלות.
בקשה
curl -X GET https://aicall.co.il/api/v1/sms/threads?limit=50&offset=0 \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"threads": [
{
"id": 7,
"ownedNumberId": 3,
"ownedNumber": "+972501111111",
"remotePhone": "+972502222222",
"remoteContactName": "Dana Levi",
"lastMessageAt": "2026-05-27T10:01:12Z",
"unreadCount": 1,
"archivedAt": null
},
{
"id": 6,
"ownedNumberId": 3,
"ownedNumber": "+972501111111",
"remotePhone": "+972503333333",
"remoteContactName": null,
"lastMessageAt": "2026-05-26T18:42:00Z",
"unreadCount": 0,
"archivedAt": null
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/sms/threadsדורש את ההרשאה sms:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"threads": [
{
"id": 7,
"ownedNumberId": 3,
"ownedNumber": "+972501111111",
"remotePhone": "+972502222222",
"remoteContactName": "Dana Levi",
"lastMessageAt": "2026-05-27T10:01:12Z",
"unreadCount": 1,
"archivedAt": null
},
{
"id": 6,
"ownedNumberId": 3,
"ownedNumber": "+972501111111",
"remotePhone": "+972503333333",
"remoteContactName": null,
"lastMessageAt": "2026-05-26T18:42:00Z",
"unreadCount": 0,
"archivedAt": null
}
]
},
"requestId": "req_abc"
}/api/v1/sms/threads/{id}קריאת היסטוריית הודעות בשיחה
מחזיר את שורת השיחה ואת היסטוריית ההודעות מהחדשה לישנה. אפשר לעבור לעמודים ישנים יותר עם ?before=<messageId>.
- כל הודעה כוללת כיוון (
outbound/inbound), גוף, מקטעים, קידוד, מצב ועלות למקטע. - שליחות שנכשלו כוללות
errorCodeו-errorMessage. - תומך גם ב-
PATCH /api/v1/sms/threads/:idעם גוף{ "markRead": true }לאיפוס מונה הלא-נקראות (אותה הרשאהsms:read).
פרמטרים
idpathnumberחובהמזהה שיחה מנקודת הקצה של הרשימה.
limitquerynumberאופציונלימספר הודעות מקסימלי להחזרה (1–500). · ברירת מחדל: 100
beforequerynumberאופציונליCursor: החזרת הודעות עם id קטן מ-before. השתמשו ב-id הנמוך ביותר מהעמוד הקודם.
בקשה
curl -X GET https://aicall.co.il/api/v1/sms/threads/id?limit=100 \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"thread": {
"id": 7,
"ownedNumberId": 3,
"ownedNumber": "+972501111111",
"remotePhone": "+972502222222",
"remoteContactName": "Dana Levi",
"lastMessageAt": "2026-05-27T10:01:12Z",
"unreadCount": 1,
"archivedAt": null
},
"messages": [
{
"id": 1042,
"direction": "outbound",
"body": "Hi Dana, your link is https://example.com/d",
"segments": 1,
"encoding": "gsm7",
"status": "delivered",
"upstreamMessageId": "msg_4f1a9c2b",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0.0472,
"sentAt": "2026-05-27T10:00:01Z",
"deliveredAt": "2026-05-27T10:00:03Z",
"createdAt": "2026-05-27T10:00:01Z"
},
{
"id": 1041,
"direction": "inbound",
"body": "Thanks!",
"segments": 1,
"encoding": "gsm7",
"status": "received",
"upstreamMessageId": "msg_3e8d7b16",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0,
"sentAt": "2026-05-27T09:59:00Z",
"deliveredAt": "2026-05-27T09:59:00Z",
"createdAt": "2026-05-27T09:59:00Z"
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
- 404השיחה לא נמצאה או לא שייכת לחשבון שלך.
ניסוי
/api/v1/sms/threads/{id}דורש את ההרשאה sms:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"thread": {
"id": 7,
"ownedNumberId": 3,
"ownedNumber": "+972501111111",
"remotePhone": "+972502222222",
"remoteContactName": "Dana Levi",
"lastMessageAt": "2026-05-27T10:01:12Z",
"unreadCount": 1,
"archivedAt": null
},
"messages": [
{
"id": 1042,
"direction": "outbound",
"body": "Hi Dana, your link is https://example.com/d",
"segments": 1,
"encoding": "gsm7",
"status": "delivered",
"upstreamMessageId": "msg_4f1a9c2b",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0.0472,
"sentAt": "2026-05-27T10:00:01Z",
"deliveredAt": "2026-05-27T10:00:03Z",
"createdAt": "2026-05-27T10:00:01Z"
},
{
"id": 1041,
"direction": "inbound",
"body": "Thanks!",
"segments": 1,
"encoding": "gsm7",
"status": "received",
"upstreamMessageId": "msg_3e8d7b16",
"errorCode": null,
"errorMessage": null,
"priceUsd": 0,
"sentAt": "2026-05-27T09:59:00Z",
"deliveredAt": "2026-05-27T09:59:00Z",
"createdAt": "2026-05-27T09:59:00Z"
}
]
},
"requestId": "req_abc"
}/api/v1/sms/threads/{id}/replyמענה בשיחה
שליחת מענה בשיחה קיימת. המספר השולח והנמען נגזרים משורת השיחה — אי אפשר לעקוף אותם.
- נספר באותה מכסה יומית כמו שליחות ישירות.
- תומך בשדות דינמיים בדיוק כמו
POST /api/v1/sms. - מחזיר מזהה הודעה חדש, מזהה שיחה, מקטעים, קידוד ועלות.
פרמטרים
idpathnumberחובהמזהה השיחה לתגובה.
גוף הבקשה
{
"body": "Got it — I'll get back to you within the hour."
}בקשה
curl -X POST https://aicall.co.il/api/v1/sms/threads/id/reply \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"Got it — I'll get back to you within the hour."}'תגובה
{
"ok": true,
"data": {
"messageId": 1044,
"threadId": 7,
"segments": 1,
"encoding": "gsm7",
"costUsd": 0.0411,
"priceUsd": 0.0472
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
- 402אין מספיק קרדיט בחשבון.
- 404השיחה לא נמצאה או לא שייכת לחשבון שלך.
- 429נגמרה המכסה היומית.
ניסוי
/api/v1/sms/threads/{id}/replyדורש את ההרשאה sms:send.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"messageId": 1044,
"threadId": 7,
"segments": 1,
"encoding": "gsm7",
"costUsd": 0.0411,
"priceUsd": 0.0472
},
"requestId": "req_abc"
}/api/v1/conversationsרשימת שיחות הקול שלך
מחזיר את שיחות הקול האחרונות שלך, חדשות תחילה (עד 200).
- כל שורה כוללת פרטי שיחה — כיוון, צדדים, משך, שפה שזוהתה, עלות וסיכום.
- השדות
data_collectionו-evaluationמחזיקים את התוצאות המובנות שהסוכן הוגדר לאסוף, לפי המזהים שהוגדרו. - לתמלול המלא לפי דובר יש לפנות לנקודת הקצה של השיחה הבודדת.
בקשה
curl -X GET https://aicall.co.il/api/v1/conversations \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"conversations": [
{
"id": 318,
"service": "voice",
"direction": "inbound",
"agent_name": "Front desk",
"to_number": "+972501111111",
"from_number": "+972502222222",
"duration_seconds": 142,
"cost_usd": "0.1180",
"main_language": "he",
"summary_title": "Booking confirmed",
"summary": "Caller booked a table for Friday at 8pm.",
"has_audio": true,
"started_at": "2026-05-27T10:00:01Z",
"ended_at": "2026-05-27T10:02:23Z",
"data_collection": {
"party_size": {
"value": 4,
"rationale": "Caller said 'four people'."
}
},
"evaluation": {
"booking_completed": {
"result": "success",
"rationale": "Reservation confirmed before hangup."
}
}
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
ניסוי
/api/v1/conversationsדורש את ההרשאה conversations:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"conversations": [
{
"id": 318,
"service": "voice",
"direction": "inbound",
"agent_name": "Front desk",
"to_number": "+972501111111",
"from_number": "+972502222222",
"duration_seconds": 142,
"cost_usd": "0.1180",
"main_language": "he",
"summary_title": "Booking confirmed",
"summary": "Caller booked a table for Friday at 8pm.",
"has_audio": true,
"started_at": "2026-05-27T10:00:01Z",
"ended_at": "2026-05-27T10:02:23Z",
"data_collection": {
"party_size": {
"value": 4,
"rationale": "Caller said 'four people'."
}
},
"evaluation": {
"booking_completed": {
"result": "success",
"rationale": "Reservation confirmed before hangup."
}
}
}
]
},
"requestId": "req_abc"
}/api/v1/conversations/{id}שליפת שיחה בודדת
מחזיר שיחה אחת כולל מערך ה-transcript המלא לפי דובר.
- כל שדות הרשימה מופיעים, ובנוסף התמלול לפי תורות.
- השדות
data_collection/evaluationיהיוnullעד שניתוח השיחה יסתיים — כדאי לבדוק שוב כמה שניות לאחר סיום השיחה. - מחזיר
404 CONVERSATION_NOT_FOUNDכשהמזהה לא שייך לחשבון שלך.
פרמטרים
idpathnumberחובהמזהה השיחה מנקודת הקצה של הרשימה.
בקשה
curl -X GET https://aicall.co.il/api/v1/conversations/id \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"id": 318,
"service": "voice",
"direction": "inbound",
"agent_name": "Front desk",
"duration_seconds": 142,
"main_language": "he",
"has_audio": true,
"data_collection": {
"party_size": {
"value": 4,
"rationale": "Caller said 'four people'."
}
},
"evaluation": {
"booking_completed": {
"result": "success",
"rationale": "Reservation confirmed before hangup."
}
},
"transcript": [
{
"role": "agent",
"message": "Hello, how can I help?",
"time_in_call_secs": 0
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
- 404השיחה לא נמצאה או לא שייכת לחשבון שלך.
ניסוי
/api/v1/conversations/{id}דורש את ההרשאה conversations:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 318,
"service": "voice",
"direction": "inbound",
"agent_name": "Front desk",
"duration_seconds": 142,
"main_language": "he",
"has_audio": true,
"data_collection": {
"party_size": {
"value": 4,
"rationale": "Caller said 'four people'."
}
},
"evaluation": {
"booking_completed": {
"result": "success",
"rationale": "Reservation confirmed before hangup."
}
},
"transcript": [
{
"role": "agent",
"message": "Hello, how can I help?",
"time_in_call_secs": 0
}
]
},
"requestId": "req_abc"
}/api/v1/jobs/runningמשימות שרצות כרגע (ידידותי לפולינג)
מחזיר את כל המשימות שרצות כרגע לחשבון המחובר — Speech to Text וכתוביות בסטטוסים שאינם סופיים (queued, processing, transcribing, burning).
- הגנה מפני שיטפון — רצפה קשיחה של שנייה אחת בין קריאות. קריאה נוספת בתוך החלון תחזיר
429 RATE_LIMITEDעםRetry-After: 1, ללא קשר לתקרה החודשית של המסלול. - ETag / 304 — לכל תגובה
ETagחלש המבוסס על זוגות (id, status) של המשימות. אפשר להחזיר אותו ב-If-None-Matchולקבל304 Not Modifiedזול כל עוד שום דבר לא השתנה. - קצב מומלץ — קריאה כל 2 שניות. הרצפה הקשיחה היא שנייה אחת.
- משימות שהושלמו או נכשלו אינן נכללות — יש לפנות ל-
/api/v1/transcribeאו ל-/api/v1/subtitlesלמצב סופי.
בקשה
curl -X GET https://aicall.co.il/api/v1/jobs/running \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"in_flight": 2,
"limit_per_user": 5,
"jobs": [
{
"kind": "speech-to-text",
"id": 91,
"status": "processing",
"file_name": "interview.mp3",
"started_at": "2026-05-24T07:30:12Z",
"created_at": "2026-05-24T07:30:00Z",
"audio_duration_sec": 360,
"language": "en",
"source": "api"
},
{
"kind": "subtitles",
"id": 12,
"status": "burning",
"file_name": "demo.mp4",
"started_at": "2026-05-24T07:31:04Z",
"created_at": "2026-05-24T07:31:00Z",
"video_duration_sec": 240,
"language": "he",
"voice_cleanup_used": true,
"source": "ui"
}
]
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
- 304מצב המשימות לא השתנה מאז ה-ETag ששלחת.
- 429פולינג מעל הרצפה של שנייה. יש להמתין לפי כותרת `Retry-After`.
ניסוי
/api/v1/jobs/runningדורש את ההרשאה profile:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"in_flight": 2,
"limit_per_user": 5,
"jobs": [
{
"kind": "speech-to-text",
"id": 91,
"status": "processing",
"file_name": "interview.mp3",
"started_at": "2026-05-24T07:30:12Z",
"created_at": "2026-05-24T07:30:00Z",
"audio_duration_sec": 360,
"language": "en",
"source": "api"
},
{
"kind": "subtitles",
"id": 12,
"status": "burning",
"file_name": "demo.mp4",
"started_at": "2026-05-24T07:31:04Z",
"created_at": "2026-05-24T07:31:00Z",
"video_duration_sec": 240,
"language": "he",
"voice_cleanup_used": true,
"source": "ui"
}
]
},
"requestId": "req_abc"
}/api/v1/profileקריאת הפרופיל ושימוש 30 הימים האחרונים
מחזיר את החשבון המחובר יחד עם סיכום שימוש מתגלגל של 30 ימים.
- זהות החשבון — id, דוא״ל, שם תצוגה, תפקיד ושפה.
- יתרה חיה בדולרים (ספר חשבונות הקרדיט הוא מקור האמת).
- פירוט הוצאה לפי שירות — דקות קוליות, ניקוי אודיו וצריבת כתוביות.
- מוני תפוקה — תמלולים, משימות כתוביות, דקות קוליות, בקשות API ושגיאות API.
בקשה
curl -X GET https://aicall.co.il/api/v1/profile \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"id": "user_abc",
"email": "you@example.com",
"name": "Sample User",
"role": "user",
"locale": "en",
"balance": {
"amount_usd": 12.34
},
"usage_last_30d": {
"total_spend_usd": 4.56,
"spend_by_service": {
"voice_minute": 1.2,
"voice_isolator": 0.5,
"subtitle_burn": 0.1
},
"transcriptions": 8,
"subtitle_jobs": 3,
"voice_minutes": 42,
"api_requests": 120,
"api_errors": 3
}
},
"requestId": "req_abc"
}תגובות
- 200הצלחה
- 401נדרש אימות.
ניסוי
/api/v1/profileדורש את ההרשאה profile:read.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": "user_abc",
"email": "you@example.com",
"name": "Sample User",
"role": "user",
"locale": "en",
"balance": {
"amount_usd": 12.34
},
"usage_last_30d": {
"total_spend_usd": 4.56,
"spend_by_service": {
"voice_minute": 1.2,
"voice_isolator": 0.5,
"subtitle_burn": 0.1
},
"transcriptions": 8,
"subtitle_jobs": 3,
"voice_minutes": 42,
"api_requests": 120,
"api_errors": 3
}
},
"requestId": "req_abc"
}/api/v1/transcribeקריאה לתמלול מקובץ אודיו/וידאו
יצירת משימת תמלול דרך גוף JSON או דרך העלאת multipart.
- גוף JSON — יש להעביר URL מאוחסן (https) או קישור יוטיוב בשדה
url. - multipart/form-data — להעלאת קובץ ישירה דרך השדה
file. - שדה
languageברירת מחדלauto— אפשר להגדיר קוד ISO מפורש לקיבוע הזיהוי. - מחזיר מזהה משימה בתור מיידית — לאחר מכן ניתן לסקור את נקודת הקצה של המשימה הבודדת או להמתין ל-Webhook לאחר הריצה.
גוף הבקשה
{
"url": "https://example.com/clip.mp3",
"language": "auto"
}בקשה
curl -X POST https://aicall.co.il/api/v1/transcribe \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/clip.mp3","language":"auto"}'תגובה
{
"ok": true,
"data": {
"id": 92,
"status": "queued"
},
"requestId": "req_abc"
}תגובות
- 202הצלחה
- 402אין מספיק קרדיט בחשבון.
- 429חרגת ממגבלת הרצה במקביל.
ניסוי
/api/v1/transcribeדורש את ההרשאה transcribe:write.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 92,
"status": "queued"
},
"requestId": "req_abc"
}/api/v1/subtitlesקריאה ליצירת כתוביות
יצירת משימת כתוביות דרך העלאת סרטון. הצינור מתמלל, מנקה אודיו במידת הצורך, וצורב את הכתוביות לתוך הסרטון.
- multipart/form-data בלבד — יש להעביר את הקובץ הבינארי דרך השדה
file. שליחה דרך URL נמצאת ב-roadmap. - שדה
use_voice_cleanupמפעיל ניקוי אודיו לפני הצריבה — משפר דיוק במקורות רועשים. - מחזיר מזהה משימה בתור ופועל לפי אותם כללי חיוב והגבלת מקבילות כמו הדשבורד.
- הכלי בדפדפן לא תומך עדיין ב-multipart — אפשר להעתיק את דוגמת ה-cURL ולבדוק מהטרמינל.
בקשה
curl -X POST https://aicall.co.il/api/v1/subtitles \
-H "Authorization: Bearer $API_KEY"תגובה
{
"ok": true,
"data": {
"id": 18,
"status": "queued"
},
"requestId": "req_abc"
}תגובות
- 202הצלחה
- 400הגוף נשלח כ-JSON במקום multipart/form-data.
- 402אין מספיק קרדיט בחשבון.
- 422במדיה שהועלתה אין רצועת אודיו.
ניסוי
/api/v1/subtitlesדורש את ההרשאה subtitles:write.בקשה
כדאי להתחבר כדי לבדוק את ה-endpoint
נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.
nav.loginתשובה
יש לשלוח בקשה כדי לראות תשובה.
{
"ok": true,
"data": {
"id": 18,
"status": "queued"
},
"requestId": "req_abc"
}דוגמאות
רשימת שיחות וקריאת הנתונים שנאספו
import os
import requests
BASE = "https://aicall.co.il/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
# 1. List the most recent conversations.
resp = requests.get(f"{BASE}/conversations", headers=HEADERS, timeout=30)
resp.raise_for_status()
conversations = resp.json()["data"]["conversations"]
if not conversations:
print("No conversations yet.")
raise SystemExit(0)
# 2. Fetch the newest one in full.
first_id = conversations[0]["id"]
detail = requests.get(f"{BASE}/conversations/{first_id}", headers=HEADERS, timeout=30)
detail.raise_for_status()
conv = detail.json()["data"]
print(f"Conversation {conv['id']} — {conv.get('summary_title') or '(no title)'}")
for identifier, field in (conv.get("data_collection") or {}).items():
print(f" collected {identifier}: {field['value']}")
for criterion, outcome in (conv.get("evaluation") or {}).items():
print(f" evaluation {criterion}: {outcome['result']}")
קריאת הפרופיל ושימוש 30 הימים האחרונים
GET /api/v1/profile קוראת את החשבון המאומת.
- מחזירה את זהות החשבון (id, דוא״ל, שם תצוגה, תפקיד ושפה).
- יתרה חיה בדולרים — מקור האמת של ספר הקרדיט.
- סיכום שימוש של 30 ימים עם פירוט הוצאה לפי שירות (דקות קוליות, ניקוי אודיו, צריבת כתוביות).
- מוני תפוקה: תמלולים, משימות כתוביות, דקות קוליות, בקשות API ושגיאות API.
- דורש את ההרשאה
profile:read.
import os
import httpx
API_BASE = "https://aicall.co.il/api/v1"
API_KEY = os.environ["API_KEY"]
def read_profile() -> dict:
res = httpx.get(
f"{API_BASE}/profile",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=15,
)
res.raise_for_status()
return res.json()["data"]
if __name__ == "__main__":
me = read_profile()
print(f"{me['email']} balance=${me['balance']['amount_usd']:.2f}")
print(f"30-day spend: ${me['usage_last_30d']['total_spend_usd']:.2f}")כותרת Authorization נדרשת תמיד.
- בקשות אנונימיות מקבלות
401עם הודעה מתורגמת. - הרשאה שגויה תחזיר
INSUFFICIENT_SCOPE— יש להנפיק מפתח חדש עםprofile:read. - אפשר לשמור את התשובה במטמון לכ-30 שניות — היתרה מתעדכנת מספר הקרדיט בפחות משנייה.
מעקב אחרי המשימות שרצות כרגע
GET /api/v1/jobs/running מחזירה את כל המשימות שרצות כרגע לחשבון המחובר — Speech to Text וכתוביות בסטטוסים שאינם סופיים.
- תוכנן לפולינג קצר — הקצב המומלץ הוא קריאה אחת כל 2 שניות.
- רצפה קשיחה: שנייה אחת בין קריאות לכל מפתח. קריאה נוספת בתוך החלון תחזיר
429 RATE_LIMITEDעםRetry-After: 1, ללא קשר לתקרה החודשית של המסלול. - לכל תגובה
ETagחלש. אפשר להחזיר אותו ב-If-None-Matchולקבל304 Not Modifiedכל עוד מצב המשימות לא השתנה — תעבורה של כ-150 בתים במקום הגוף המלא. - משימות שהושלמו או נכשלו אינן נכללות — יש לקרוא ל-
/api/v1/transcribeאו ל-/api/v1/subtitlesלמצב סופי. - דורש את ההרשאה
profile:read.
import os
import time
import httpx
API_BASE = "https://aicall.co.il/api/v1"
API_KEY = os.environ["API_KEY"]
POLL_SEC = 2 # recommended cadence; hard floor is 1 s
def watch_running_jobs():
last_etag = None
while True:
headers = {"Authorization": f"Bearer {API_KEY}"}
if last_etag:
headers["If-None-Match"] = last_etag
res = httpx.get(f"{API_BASE}/jobs/running", headers=headers, timeout=15)
if res.status_code == 304:
# Nothing changed — cheap response, no body to parse.
pass
elif res.status_code == 429:
# Polled too fast — honour the server's retry hint.
retry = int(res.headers.get("Retry-After", "1"))
time.sleep(retry)
continue
else:
res.raise_for_status()
last_etag = res.headers.get("ETag", last_etag)
payload = res.json()["data"]
print(f"{payload['in_flight']} job(s) running:")
for job in payload["jobs"]:
started = job.get("started_at") or "(still queued)"
print(f" - {job['kind']} #{job['id']} {job['status']} {started}")
time.sleep(POLL_SEC)
if __name__ == "__main__":
watch_running_jobs()הדפוס מטה הוא חוזה הלקוח המומלץ:
- כדאי לשמור את ה-
ETagבין קריאות ולהחזיר אותו ב-If-None-Match— השרת מחזיר304כשאין שינוי, כך שרוב הפולינג כמעט חינם. - יש לכבד
Retry-Afterבתגובת429— הרצפה חלה ללא קשר למסלול, ולכן גם מפתח אדמין יקבל אותה כשהקריאות תכופות מדי. - הסטטוסים שכדאי לעקוב אחריהם הם
queued,processing(Speech to Text), ו-transcribing/burning(כתוביות). ברגע שמשימה נעלמת מהרשימה, אפשר לשלוף את שורתה הסופית מנקודת הקצה של הצינור הרלוונטי.
קריאה לתמלול מקובץ אודיו/וידאו
POST /api/v1/transcribe יוצרת משימת תמלול מקובץ או מ-URL.
- העלאת multipart — לשלוח את הקובץ הבינארי בשדה
file. - גוף JSON — להעביר URL מאוחסן (https) או קישור יוטיוב בשדה
url. - מחזירה
202עם מזהה משימה בתור מיד — כדאי לסקור אתGET /api/v1/transcribe/{id}עד שהסטטוס יתחלף ל-done. - אפשר להגדיר
languageלקוד ISO ספציפי (en,heוכו׳) או להשאירautoלזיהוי אוטומטי. - דורש את ההרשאה
transcribe:write.
import os
import time
import httpx
API_BASE = "https://aicall.co.il/api/v1"
API_KEY = os.environ["API_KEY"]
def submit_transcription(path: str, language: str = "auto") -> int:
with open(path, "rb") as f:
res = httpx.post(
f"{API_BASE}/transcribe",
files={"file": (os.path.basename(path), f, "audio/mpeg")},
data={"language": language},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=60,
)
res.raise_for_status()
return res.json()["data"]["id"]
def poll_until_done(job_id: int) -> dict:
while True:
res = httpx.get(
f"{API_BASE}/transcribe/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=15,
)
res.raise_for_status()
data = res.json()["data"]
if data["status"] in ("done", "failed"):
return data
time.sleep(2)
job_id = submit_transcription("./meeting.mp3")
print("queued:", job_id)
final = poll_until_done(job_id)
print(final["transcript_text"][:200])נקודות חשובות על מכסות:
- מגבלת העלאה 500 MB — זהה לדשבורד.
- מגבלות מקבילות משותפות לממשק ול-API. חריגה מהמגבלה למשתמש תחזיר
429 TOO_MANY_JOBS. - חשבון ריק יחזיר
402 INSUFFICIENT_BALANCEעם הסכום הנדרש מול היתרה בשדהdetails. - סרטונים שקטים (ללא רצועת אודיו) יחזירו
422 NO_AUDIO_STREAM— יש לקודד מחדש עם ערוץ אודיו.
קריאה ליצירת כתוביות
POST /api/v1/subtitles מפעילה את צינור הכתוביות המלא על וידאו שעלה.
- multipart בלבד — לשלוח את הקובץ הבינארי בשדה
file; שליחה דרך URL עדיין לא נתמכת. - הצינור מתמלל, מנקה אודיו רועש בעת הצורך (כש-
use_voice_cleanup=true), ולבסוף צורב את הכתוביות לתוך הסרטון. - מחזירה
202עם מזהה משימה; כדאי לסקור אתGET /api/v1/subtitlesעד שהסטטוס יתחלף ל-doneוקישור הסרטון הצרוב יופיע. - השדה
styleמקבל JSON אופציונלי (פונט, גודל, צבע ראשי/מתאר, מיקום אנכי) — אותה צורה שעורך הדשבורד שומר. - דורש את ההרשאה
subtitles:write.
import os
import httpx
API_BASE = "https://aicall.co.il/api/v1"
API_KEY = os.environ["API_KEY"]
def submit_subtitles(path: str, language: str = "auto", clean_audio: bool = False) -> int:
with open(path, "rb") as f:
res = httpx.post(
f"{API_BASE}/subtitles",
files={"file": (os.path.basename(path), f, "video/mp4")},
data={
"language": language,
"use_voice_cleanup": "true" if clean_audio else "false",
"style": '{"font":"Noto Sans Hebrew","fontSize":28,"primaryColor":"#FFFFFF","outlineColor":"#000000","position":"bottom","marginV":40}',
},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=120,
)
res.raise_for_status()
return res.json()["data"]["id"]
job_id = submit_subtitles("./talk.mp4", language="he", clean_audio=True)
print("queued:", job_id)נקודות שכדאי לקחת בחשבון:
- סרטונים ארוכים יכולים לקחת מספר דקות — עדיף לסקור כל 10–15 שניות, לא מהר יותר.
- ניקוי האודיו מוסיף חיוב לפי דקה מעבר לחיוב התמלול; כדאי לדלג עליו כשהאודיו נקי מלכתחילה.
- שפות RTL (עברית, ערבית) דורשות פונט שתומך בהן בשדה
style.font— ברירות המחדל מוגדרות בצד השרת. - נערך SRT בדשבורד? אפשר להפעיל
POST /api/v1/subtitles/{id}/reburnכדי לצרוב מחדש את הסרטון בחינם (ללא חיוב תמלול).
