עיון בתמיכה ובעזרה

תיעוד למפתחים

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 במידת האפשר.
bash
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 } בשגיאת יתרה לא מספיקה).
application/json
{
  "ok": true,
  "data": {
    "id": "user_abc",
    "email": "you@example.com",
    "balance": { "amount_usd": 12.34 }
  },
  "requestId": "req_4f1b2a3d"
}
application/json
{
  "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.
application/json
{
  "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 מותאם.
application/json
{
  "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 — האדמין עדיין לא חיבר את שירות הקול. אפשר לפנות אלינו ונסדר את זה בצד שלנו.
application/json
{
  "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, ואותה גביית קרדיט שיש בדשבורד. כל נקודת קצה מתועדת עם טבלת פרמטרים, קודי תגובה, דוגמאות קוד וכלי ניסוי בדפדפן.

כתובת בסיס
אימות
Authorization: Bearer $API_KEY
מבנה תגובה
כל תגובה מכילה ok, data או error, ושדה requestId.
מגבלת קצב
ברירת מחדל 60 לדקה · 1,000 לשעה לכל מפתח. קיימים מסלולים גבוהים יותר.
תגובת הצלחה

ok=true ואובייקט data שמותאם לנקודת הקצה.

application/json
{
  "ok": true,
  "data": { /* endpoint-specific payload */ },
  "requestId": "req_4f1b2a3d"
}
תגובת שגיאה

ok=false עם קוד יציב ועם הודעה ידידותית בשפת המבקש.

application/json
{
  "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
curl https://aicall.co.il/api/v1/profile \
  -H "Authorization: Bearer $API_KEY"
Python
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())
Node.js
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

GET/api/v1/health

בריאות השירות (ללא אימות)

בדיקת זמינות קלת משקל לשימוש כלי ניטור.

  • מחזיר 200 כאשר היישום ובסיס הנתונים פעילים.
  • בטוח לסקור בכל קצב — אין צורך באימות.
  • הגרסה המעמיקה (?deep=true) למפתחות אדמין בלבד וחושפת זמני תגובה של ספקים.

בקשה

curl -X GET https://aicall.co.il/api/v1/health \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "ok": true,
  "data": {
    "status": "healthy",
    "time": "2026-05-22T08:00:00Z",
    "version": "1.2.5",
    "uptimeSec": 1234
  },
  "requestId": "req_abc"
}

תגובות

  • 200הצלחה

ניסוי

GET/api/v1/health
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "ok": true,
  "data": {
    "status": "healthy",
    "time": "2026-05-22T08:00:00Z",
    "version": "1.2.5",
    "uptimeSec": 1234
  },
  "requestId": "req_abc"
}
GET/api/v1/keys
דורש את ההרשאה keys:manage.

רשימת מפתחות ה-API שלך

מחזיר את כל המפתחות של מבקש הקריאה (או את כולם כאשר נקרא עם מפתח אדמין).

  • הסוד המלא לעולם לא נחשף — רק קידומת מוסתרת.
  • גם מפתחות שבוטלו או פגו מופיעים, עם חותמות הזמן של revoked_at / expires_at.
  • שימוש מצוין למעקב אחר אילו מפתחות בשימוש ומתי נראו לאחרונה.

בקשה

curl -X GET https://aicall.co.il/api/v1/keys \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "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הצלחה

ניסוי

GET/api/v1/keysדורש את ההרשאה keys:manage.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
POST/api/v1/keys
דורש את ההרשאה keys:manage.

יצירת מפתח API חדש

יוצר מפתח חדש ומחזיר את הסוד המלא פעם אחת בלבד.

  • מפתחות משתמש חייבים לפוג תוך 365 ימים; מפתחות אדמין יכולים להיות ללא תוקף.
  • ה-Scope מאומת מול רמת המבקש — Scope אדמין נדחה במפתחות משתמש.
  • חובה לשמור את הסוד מיד — הוא לא יוצג שוב, רק קידומת מוסתרת.

גוף הבקשה

application/json
{
  "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"}'

תגובה

201הצלחה
{
  "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 ימים.

ניסוי

POST/api/v1/keysדורש את ההרשאה keys:manage.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

201דוגמת תשובה
{
  "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"
}
GET/api/v1/transcribe
דורש את ההרשאה transcribe:read.

רשימת משימות התמלול שלך

מחזיר את משימות התמלול האחרונות, חדשות תחילה.

  • כולל פרטי קובץ, שפה מזוהה ותמונת מצב של עלות לכל משימה.
  • שדה status משקף את מצב הצינור: queued · processing · done · failed.
  • לקבלת חותמות זמן ברמת מילה יש לפנות לנקודת הקצה של המשימה הבודדת.

בקשה

curl -X GET https://aicall.co.il/api/v1/transcribe \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "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הצלחה

ניסוי

GET/api/v1/transcribeדורש את ההרשאה transcribe:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/transcribe/{id}
דורש את ההרשאה transcribe:read.

שליפת תמלול בודד

מחזיר את התמלול המלא, כולל חותמות זמן ברמת מילה, ברגע שהמשימה מסומנת 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"

תגובה

200הצלחה
{
  "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הצלחה

ניסוי

GET/api/v1/transcribe/{id}דורש את ההרשאה transcribe:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/transcribe/{id}/export
דורש את ההרשאה transcribe:read.

הורדת תמלול

מחזיר את התמלול בפורמט המבוקש.

  • 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"

תגובה

200הצלחה
We started by going over the proposal — let me know if you have questions…

תגובות

  • 200הצלחה

ניסוי

GET/api/v1/transcribe/{id}/exportדורש את ההרשאה transcribe:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
We started by going over the proposal — let me know if you have questions…
GET/api/v1/subtitles
דורש את ההרשאה subtitles:read.

רשימת משימות כתוביות

מחזיר את משימות הכתוביות האחרונות עם פרטי עלות וקישור לסרטון הצרוב.

  • בכל שורה מצוין דגל ניקוי אודיו, עלות הצריבה ומשך הסרטון המקורי.
  • הכתובת output_video_url חתומה ועוברת דרך הדומיין שלנו — ללא חשיפת ספק.
  • להורדת קובץ .srt יש להשתמש בנקודת הקצה הייעודית.

בקשה

curl -X GET https://aicall.co.il/api/v1/subtitles \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "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הצלחה

ניסוי

GET/api/v1/subtitlesדורש את ההרשאה subtitles:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/subtitles/{id}/srt
דורש את ההרשאה subtitles:read.

הורדת קובץ 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"

תגובה

200הצלחה
1
00:00:01,000 --> 00:00:03,500
Hello there!

תגובות

  • 200הצלחה

ניסוי

GET/api/v1/subtitles/{id}/srtדורש את ההרשאה subtitles:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
1
00:00:01,000 --> 00:00:03,500
Hello there!
POST/api/v1/subtitles/{id}/reburn
דורש את ההרשאה subtitles:write.

צריבה מחדש לאחר עריכת SRT (חינם)

מריץ מחדש את שלב הצריבה לפי ה-SRT הנוכחי.

  • ללא חיוב על תמלול או ניקוי אודיו — רק ffmpeg מורץ.
  • שימושי כשטקסט הכתוביות נערך וצריך לרענן את התצוגה בסרטון.
  • הכתובת של פלט הצריבה מתעדכנת בשורת המשימה כשהריצה מסתיימת.

פרמטרים

idpathstringחובה

בקשה

curl -X POST https://aicall.co.il/api/v1/subtitles/id/reburn \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "ok": true,
  "data": {
    "id": 7,
    "reburned": true
  },
  "requestId": "req_abc"
}

תגובות

  • 200הצלחה

ניסוי

POST/api/v1/subtitles/{id}/reburnדורש את ההרשאה subtitles:write.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "ok": true,
  "data": {
    "id": 7,
    "reburned": true
  },
  "requestId": "req_abc"
}
POST/api/v1/sms
דורש את ההרשאה sms:send.

שליחת 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/יום לישראל (ניתן לכיוון על ידי האדמין).

גוף הבקשה

application/json
{
  "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"}}]}'

תגובה

202הצלחה
{
  "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.

ניסוי

POST/api/v1/smsדורש את ההרשאה sms:send.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

202דוגמת תשובה
{
  "ok": true,
  "data": {
    "jobId": 17,
    "recipientCount": 2,
    "estimatedCostUsd": 0.0822,
    "estimatedPriceUsd": 0.0944,
    "perCountry": {
      "IL": 2
    }
  },
  "requestId": "req_abc"
}
GET/api/v1/sms/jobs/{id}
דורש את ההרשאה sms:read.

בדיקת אצוות 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"

תגובה

200הצלחה
{
  "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האצווה לא נמצאה או לא שייכת לחשבון שלך.

ניסוי

GET/api/v1/sms/jobs/{id}דורש את ההרשאה sms:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/sms/threads
דורש את ההרשאה sms:read.

רשימת שיחות 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"

תגובה

200הצלחה
{
  "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הצלחה

ניסוי

GET/api/v1/sms/threadsדורש את ההרשאה sms:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/sms/threads/{id}
דורש את ההרשאה sms:read.

קריאת היסטוריית הודעות בשיחה

מחזיר את שורת השיחה ואת היסטוריית ההודעות מהחדשה לישנה. אפשר לעבור לעמודים ישנים יותר עם ?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"

תגובה

200הצלחה
{
  "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השיחה לא נמצאה או לא שייכת לחשבון שלך.

ניסוי

GET/api/v1/sms/threads/{id}דורש את ההרשאה sms:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
POST/api/v1/sms/threads/{id}/reply
דורש את ההרשאה sms:send.

מענה בשיחה

שליחת מענה בשיחה קיימת. המספר השולח והנמען נגזרים משורת השיחה — אי אפשר לעקוף אותם.

  • נספר באותה מכסה יומית כמו שליחות ישירות.
  • תומך בשדות דינמיים בדיוק כמו POST /api/v1/sms.
  • מחזיר מזהה הודעה חדש, מזהה שיחה, מקטעים, קידוד ועלות.

פרמטרים

idpathnumberחובה

מזהה השיחה לתגובה.

גוף הבקשה

application/json
{
  "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."}'

תגובה

200הצלחה
{
  "ok": true,
  "data": {
    "messageId": 1044,
    "threadId": 7,
    "segments": 1,
    "encoding": "gsm7",
    "costUsd": 0.0411,
    "priceUsd": 0.0472
  },
  "requestId": "req_abc"
}

תגובות

  • 200הצלחה
  • 402אין מספיק קרדיט בחשבון.
  • 404השיחה לא נמצאה או לא שייכת לחשבון שלך.
  • 429נגמרה המכסה היומית.

ניסוי

POST/api/v1/sms/threads/{id}/replyדורש את ההרשאה sms:send.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "ok": true,
  "data": {
    "messageId": 1044,
    "threadId": 7,
    "segments": 1,
    "encoding": "gsm7",
    "costUsd": 0.0411,
    "priceUsd": 0.0472
  },
  "requestId": "req_abc"
}
GET/api/v1/conversations
דורש את ההרשאה conversations:read.

רשימת שיחות הקול שלך

מחזיר את שיחות הקול האחרונות שלך, חדשות תחילה (עד 200).

  • כל שורה כוללת פרטי שיחה — כיוון, צדדים, משך, שפה שזוהתה, עלות וסיכום.
  • השדות data_collection ו-evaluation מחזיקים את התוצאות המובנות שהסוכן הוגדר לאסוף, לפי המזהים שהוגדרו.
  • לתמלול המלא לפי דובר יש לפנות לנקודת הקצה של השיחה הבודדת.

בקשה

curl -X GET https://aicall.co.il/api/v1/conversations \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "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הצלחה

ניסוי

GET/api/v1/conversationsדורש את ההרשאה conversations:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/conversations/{id}
דורש את ההרשאה conversations:read.

שליפת שיחה בודדת

מחזיר שיחה אחת כולל מערך ה-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"

תגובה

200הצלחה
{
  "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השיחה לא נמצאה או לא שייכת לחשבון שלך.

ניסוי

GET/api/v1/conversations/{id}דורש את ההרשאה conversations:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/jobs/running
דורש את ההרשאה profile:read.

משימות שרצות כרגע (ידידותי לפולינג)

מחזיר את כל המשימות שרצות כרגע לחשבון המחובר — 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"

תגובה

200הצלחה
{
  "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`.

ניסוי

GET/api/v1/jobs/runningדורש את ההרשאה profile:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
GET/api/v1/profile
דורש את ההרשאה profile:read.

קריאת הפרופיל ושימוש 30 הימים האחרונים

מחזיר את החשבון המחובר יחד עם סיכום שימוש מתגלגל של 30 ימים.

  • זהות החשבון — id, דוא״ל, שם תצוגה, תפקיד ושפה.
  • יתרה חיה בדולרים (ספר חשבונות הקרדיט הוא מקור האמת).
  • פירוט הוצאה לפי שירות — דקות קוליות, ניקוי אודיו וצריבת כתוביות.
  • מוני תפוקה — תמלולים, משימות כתוביות, דקות קוליות, בקשות API ושגיאות API.

בקשה

curl -X GET https://aicall.co.il/api/v1/profile \
  -H "Authorization: Bearer $API_KEY"

תגובה

200הצלחה
{
  "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נדרש אימות.

ניסוי

GET/api/v1/profileדורש את ההרשאה profile:read.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

200דוגמת תשובה
{
  "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"
}
POST/api/v1/transcribe
דורש את ההרשאה transcribe:write.

קריאה לתמלול מקובץ אודיו/וידאו

יצירת משימת תמלול דרך גוף JSON או דרך העלאת multipart.

  • גוף JSON — יש להעביר URL מאוחסן (https) או קישור יוטיוב בשדה url.
  • multipart/form-data — להעלאת קובץ ישירה דרך השדה file.
  • שדה language ברירת מחדל auto — אפשר להגדיר קוד ISO מפורש לקיבוע הזיהוי.
  • מחזיר מזהה משימה בתור מיידית — לאחר מכן ניתן לסקור את נקודת הקצה של המשימה הבודדת או להמתין ל-Webhook לאחר הריצה.

גוף הבקשה

application/json
{
  "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"}'

תגובה

202הצלחה
{
  "ok": true,
  "data": {
    "id": 92,
    "status": "queued"
  },
  "requestId": "req_abc"
}

תגובות

  • 202הצלחה
  • 402אין מספיק קרדיט בחשבון.
  • 429חרגת ממגבלת הרצה במקביל.

ניסוי

POST/api/v1/transcribeדורש את ההרשאה transcribe:write.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

202דוגמת תשובה
{
  "ok": true,
  "data": {
    "id": 92,
    "status": "queued"
  },
  "requestId": "req_abc"
}
POST/api/v1/subtitles
דורש את ההרשאה subtitles:write.

קריאה ליצירת כתוביות

יצירת משימת כתוביות דרך העלאת סרטון. הצינור מתמלל, מנקה אודיו במידת הצורך, וצורב את הכתוביות לתוך הסרטון.

  • 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"

תגובה

202הצלחה
{
  "ok": true,
  "data": {
    "id": 18,
    "status": "queued"
  },
  "requestId": "req_abc"
}

תגובות

  • 202הצלחה
  • 400הגוף נשלח כ-JSON במקום multipart/form-data.
  • 402אין מספיק קרדיט בחשבון.
  • 422במדיה שהועלתה אין רצועת אודיו.

ניסוי

POST/api/v1/subtitlesדורש את ההרשאה subtitles:write.
בקשה

כדאי להתחבר כדי לבדוק את ה-endpoint

נייצר מפתח בדיקה זמני לשעה אחת לסשן — מפתחות ה-API האמיתיים נשארים בצד השרת.

nav.login
תשובה

יש לשלוח בקשה כדי לראות תשובה.

202דוגמת תשובה
{
  "ok": true,
  "data": {
    "id": 18,
    "status": "queued"
  },
  "requestId": "req_abc"
}

דוגמאות

רשימת שיחות וקריאת הנתונים שנאספו

מציג את שיחות הקול האחרונות, שולף שיחה אחת ומדפיס את הנתונים המובנים שהסוכן אסף (data_collection) יחד עם תוצאות ההערכה.
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']}")
השדות data_collection ו-evaluation יהיו null עד שניתוח השיחה מסתיים — כדאי לנסות שוב כמה שניות אחרי סיום השיחה אם הם ריקים.

קריאת הפרופיל ושימוש 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 כדי לצרוב מחדש את הסרטון בחינם (ללא חיוב תמלול).

שאלות נוספות?

נשמח לעזור — ניתן לפנות בדוא״ל לכל שאלת אונבורדינג או אינטגרציה.