תיעוד ה-API

אפליקציית הווב בכתובת האתר משרתת את ה-API הציבורי; מנוע החילוץ שמאחוריה לעולם אינו חשוף. כל תשובה היא JSON.

אימות

צרו מפתח תחת מפתחות API באפליקציה (מוצג פעם אחת) ושלחו אותו כ-bearer token. מפתחות עובדים גם בענן וגם בהתקנה עצמית.

Authorization: Bearer ak_…

דרישות מהתמונה

  • מסמך אחד לכל תמונה או עמוד PDF; מ-PDF נקרא רק העמוד הראשון. תעודה עם הספח שלה על A4 אחד, או צ'ק משני צדדיו בסריקה אחת, נחשבים מסמך אחד.
  • פורמטים: JPEG, PNG, WebP או PDF, עד 30 MB.
  • רזולוציה: 150 dpi ומעלה. מתחת ל-150 dpi איכות הקריאה אינה מובטחת.
  • המסמך כולו בתוך הפריים, שטוח ומואר באופן אחיד, בלי בוהק; סריקה עדיפה על צילום.
  • התשובה מדווחת על הרזולוציה המשוערת של כל מסמך ב-regions[].dpi ומוסיפה אזהרה מתחת ל-150 dpi.

נקודות קצה

חילוץ

שיטהנתיבתיאור
POST/api/v1/extractשדה multipart בשם file (תמונה או PDF, עד 30 MB; מ-PDF נקרא העמוד הראשון, עמודים נוספים מדווחים ב-warnings; עמודים מוקטנים בקליטה לצלע ארוכה של A4 ב-300 dpi) → שדות עם רמת ביטחון לכל שדה, דוח אימות, אזהרות, אזורים שזוהו, ו-meta (document_id, mode, trial_remaining, backend, model). המתינו עד ENGINE_TIMEOUT_MS (10 דקות כברירת מחדל) — בקשות עומדות בתור זו אחר זו. סרקו ב-150 dpi ומעלה (ראו דרישות מהתמונה). שדה multipart אופציונלי check_registries — אך ורק true / false באותיות קטנות (למשל True בפייתון אינו באותיות קטנות ומחזיר 400 INVALID_BODY) — מריץ או מדלג על הבדיקה במאגרים לבקשה זו, בלי קשר להגדרות.
GET/api/v1/documents?limit=&offset=מטא-נתונים בעמודים, מהחדש לישן: מזהה, זמן, סטטוס, סוג מסמך, תוצאת אימות, מצב, מקור, משך. לעולם לא תוכן המסמך.
GET/api/v1/documents/:idהתוצאה השמורה, מפוענחת — רק אם שמירת תוצאות הייתה פעילה באותה בקשה (אחרת 404 NOT_STORED).
DELETE/api/v1/documents/:idמוחק את התוצאה השמורה → 204.
DELETE/api/v1/documentsמוחק את כל התוצאות השמורות → { "deleted": n }.
GET/api/v1/usageמצב (local / trial / byok), מוני ניסיון (trial_remaining הוא null ו-unlimited הוא true לחשבונות שמנהל פטר מהמכסה), מסמכים החודש, סך הכול.
שיטהנתיבתיאור
GET/api/v1/registries/search?id=&bank=&branch=&account=&name=חיפוש במאגרים שהורדו כמו בדף המאגרים: השדות שמולאו מצטרפים (AND), מילות שם מותאמות כתחילית, עד 50 שורות לכל מקור עם total אמיתי. → groups[] (מקורות עם תוצאות קודם: source, loaded, data_date, fetched_at, total, name_only, rows) — name_only מסמן שורת מאגר המטה ללוחמה בטרור שהותאמה לפי שם בלבד, בלי מספר זהות, ולכן יש לאמת אותה — ו-skipped[] (source, missing: השדות שמולאו שאותו מקור אינו נושא). לא נספר כשימוש.

הגדרות

שיטהנתיבתיאור
GET/api/v1/settingsההגדרות של בעל המפתח: store_results, check_registries, backend, model, local_model, וגם model_choices ו-default_model. מפתח Anthropic לעולם אינו מוצג.
PATCH/api/v1/settingsJSON עם כל אחד מהשדות store_results, check_registries (בוליאניים), model, backend, local_model → אותו גוף כמו GET. חלים כללי דף ההגדרות: בענן model חייב להיות אחד מ-model_choices; backend ו-local_model חלים רק על התקנה עצמית. מפתח יכול לכבות את store_results אך לא להפעיל אותו (403 SESSION_REQUIRED, דבר לא מוחל; שליחת true כשהשמירה כבר פעילה מותרת): שמירת תוצאות מופעלת רק מהממשק המחובר, כך שמפתח שדלף אינו יכול להתחיל לשמור מסמכים; גם מפתח Anthropic ומפתחות ה-API נשארים זמינים מהסשן בלבד.

ניהול מפתחות (/api/keys), הנתיבים של דף ההגדרות עצמו (/api/settings, כולל מפתח Anthropic) ומצב המאגרים (/api/registries) זמינים מהממשק בלבד: הם מקבלים את סשן הדפדפן ומחזירים 403 SESSION_REQUIRED למפתח bearer. מפתח קורא ומשנה את הגדרות בעליו דרך /api/v1/settings.

מגבלות

  • בקשות: כל מפתח API מקבל 30 בקשות בדקה על פני /api/v1/* ומכסה נפרדת של 20 בדקה לחיפוש במאגרים. רצף עד המכסה עובר, ואחריו הבקשות מתחדשות אחת-אחת; מעבר לכך התשובה היא 429 RATE_LIMITED עם Retry-After בשניות. סשן דפדפן מחובר נספר לפי משתמש.
  • בהתקנה עצמית קובעים אותן ב-API_RATE_LIMIT_PER_MIN וב-API_SEARCH_RATE_LIMIT_PER_MIN (0 = ללא מגבלה); המונים נשמרים בזיכרון השרת ומתאפסים כשהוא מופעל מחדש.
  • העלאות: תמונה או PDF אחד לבקשה, עד 30 MB; מ-PDF נקרא רק העמוד הראשון.
  • המתנה: חילוץ יכול להימשך עד 10 דקות כולל ההמתנה בתור של המנוע; תור מלא מחזיר 503 עם Retry-After.
  • ניסיון: בענן חשבון חדש קורא מספר מוגבל של מסמכים על המפתח של השירות, ואז 402 TRIAL_EXHAUSTED — יש להוסיף מפתח Anthropic בהגדרות כדי להמשיך.
  • חיפוש במאגרים: עד 50 שורות לכל מקור עם total אמיתי; חיפוש דורש מספר, חשבון או לפחות שתי אותיות של שם.
  • תוצאות שמורות: תוצאה נשמרת רק כש-store_results פעיל; מפתח יכול לכבות אותו, ורק הממשק המחובר מפעיל אותו.

מבנה התשובה

  • תאריכים בפורמט ISO בכל מקום; date_of_expiry של disability_card הוא חודש ISO (2031-03).
  • validation.overall: verified / partial / unverified / mismatch. מסמכים ללא MRZ (תעודות למינציה ישנות, תעודת נכה) הם unverified במכוון.
  • document_type: teudat_zehut, teudat_zehut_back, teudat_zehut_sefach, israeli_passport, foreign_passport, israeli_drivers_license, cheque, cheque_back, senior_citizen_card, disability_card, weapon_license, unreadable, not_a_document.
  • foreign_passport נושא שמות בלטינית, מספר דרכון, אזרחות, מין ותאריכים — בלי שמות בעברית ובלי מספר זהות ישראלי. disability_card נושא שמות בשני הכתבים, id_number,‏ file_number ו-date_of_expiry.
  • senior_citizen_card ו-weapon_license נקראים בסכימה הגנרית: מיטב המאמץ, עם אזהרה.
  • not_a_document (HTTP 200, fields: {}): לא נמצא מסמך נתמך בעמוד; regions[] מפרט את מה שזוהה כ-skipped. הערך other מופיע ב-regions[] בלבד.
  • כמה מסמכים בעמוד אחד: נקראים מסמך אחד ומלוויו (תעודה + ספח, חזית צ'ק + גב), והשאר skipped.
  • regions[]: רשומה אחת לכל מסמך שזוהה — bbox_2d הוא [x1, y1, x2, y2] בטווח 0–1000 מרוחב העמוד ומגובהו (בקובץ PDF: מידות הרינדור של המנוע), ולצידו סוג האזור ורזולוציית המקור המשוערת (dpi).
  • sefach נושא את הספח כשהעמוד כלל אותו (אחרת null), ו-usage[] את מספרי הטוקנים של כל קריאה למודל, כדי שאפשר יהיה לחשב עלות בצד הקורא.
  • registries הוא null אלא אם שדה check_registries של הבקשה, או (כשהוא חסר) הגדרת בעל המפתח, הפעילו את הבדיקה. אז הוא מפרט כל מקור (id, loaded, data_date) ואת matches[]: level (alert או info), source, by (id, account או name), field ורשומת המאגר record.
  • registries.checked מפרט את המפתחות שנבדקו מול מקור מורד אחד לפחות (id_number, spouse_id_number, child_id_number, drawer_id_number, guarantor_id_number, account, name_he, name_en). רשימה ריקה פירושה ששום דבר לא נבדק — לא תוצאה נקייה.
  • התאמות שם הן התאמות של מילים שלמות מול רשימת הפעילים של המטה ללוחמה כלכלית בטרור — יש לאמת אותן. בדיקה שלא בוצעה מוחזרת כ־{"error": "REGISTRIES_UNAVAILABLE"} ואינה מכשילה את החילוץ.
{
  "document_type": "teudat_zehut",
  "fields": {
    "last_name_he": {
      "value": "ישראלי",
      "confidence": "high"
    },
    "first_name_he": {
      "value": "ישראל",
      "confidence": "high"
    },
    "id_number": {
      "value": "123456782",
      "confidence": "high"
    },
    "date_of_birth": {
      "value": "1990-01-31",
      "confidence": "high"
    },
    "date_of_issue": {
      "value": "2020-05-01",
      "confidence": "high"
    },
    "date_of_expiry": {
      "value": "2030-05-01",
      "confidence": "medium"
    }
  },
  "validation": {
    "mrz_present": false,
    "id_number_checksum_valid": true,
    "cross_checks": [],
    "overall": "unverified"
  },
  "warnings": [],
  "regions": [
    {
      "label": "document",
      "bbox_2d": [
        120,
        80,
        880,
        560
      ],
      "document_type": "teudat_zehut",
      "dpi": 300
    }
  ],
  "sefach": null,
  "registries": null,
  "model": "anthropic/claude-opus-5",
  "usage": [
    {
      "backend": "anthropic",
      "model": "claude-opus-5",
      "schema_name": "AnthropicPageExtraction",
      "input_tokens": 1583,
      "output_tokens": 214,
      "cache_read_tokens": 1201,
      "cache_write_tokens": 0
    }
  ],
  "meta": {
    "mode": "byok",
    "trial_remaining": null,
    "backend": "anthropic",
    "model": "claude-opus-5",
    "document_id": "0b1c…"
  }
}

נתוני עלות

עמודת העלות וסיכומי לוח הבקרה מחושבים מקומית מספירת הטוקנים של המנוע לכל קריאה, לפי מחירון Anthropic נכון ל-2026-06-24 (קלט, פלט, קריאה וכתיבה של מטמון, לפי מודל). זו הערכה בלבד: המחירים משתנים והטבלה מתעדכנת ידנית — החשבון האמיתי הוא דף השימוש בחשבון Anthropic שלכם. מסמך שעובד ב-Ollama אינו עולה דבר ומוצג בקו מפריד.

שגיאות

כל שגיאה נושאת קוד קריא למכונה; שדות נוספים תלויים בקוד.

{ "error": "TRIAL_EXHAUSTED", "detail": "…", "trial_docs": 5 }
סטטוסקודתיאור
401TOKEN_INVALIDמפתח לא מוכר, פגום או מבוטל.
401UNAUTHENTICATEDללא פרטי הזדהות (מצב ענן).
402TRIAL_EXHAUSTEDהמסמכים החינמיים נוצלו — הוסיפו מפתח Anthropic בהגדרות.
400NO_FILEאין חלק file בבקשה.
400NOT_IMAGEהקובץ אינו תמונה או PDF.
400INVALID_BODYלשדה יש סוג או ערך שגוי (למשל check_registries שאינו true/false).
400INVALID_MODELmodel אינו אחד מ-model_choices.
400INVALID_QUERYחיפוש במאגרים דורש מספר, חשבון או שתי אותיות של שם.
400ANTHROPIC_KEY_INVALIDAnthropic דחתה את המפתח השמור בהגדרות.
403SESSION_REQUIREDנתיב לסשן בלבד נקרא עם מפתח API.
404NOT_FOUNDאין מסמך כזה בחשבון הזה.
404NOT_STOREDהמסמך קיים אך תוצאתו לא נשמרה.
413TOO_LARGEמעל 30 MB.
429RATE_LIMITEDחריגה ממכסת הבקשות של המפתח: כברירת מחדל 30 בקשות בדקה ל-/api/v1/*, ומכסה נפרדת של 20 לחיפוש במאגרים. יש לנסות שוב אחרי מספר השניות ב-Retry-After (גם retry_after בגוף התשובה).
500KEY_DECRYPT_FAILEDמפתח ההצפנה של השרת השתנה מאז שהערך נשמר.
500INTERNALשגיאת שרת בלתי צפויה — נסו שוב מאוחר יותר.
502ENGINE_MISCONFIGUREDהמנוע דחה את הסוד של אפליקציית הווב (שגיאת פריסה).
503ENGINE_UNAVAILABLEהמנוע אינו נגיש.
504ENGINE_TIMEOUTהחילוץ לא הסתיים בתוך ENGINE_TIMEOUT_MS.
ENGINE_ERRORהסטטוס והפירוט של המנוע עצמו מועברים כמו שהם — למשל 503 עם Retry-After כשהתור מלא, 422 כשהמודל סירב לתמונה.

דוגמאות

חילוץ מסמך ובדיקתו מול המאגרים

curl -s -X POST https://makor.pro/api/v1/extract \
  -H "Authorization: Bearer ak_…" \
  -F "file=@document.jpg" \
  -F "check_registries=true"

חיפוש במאגרים

curl -s "https://makor.pro/api/v1/registries/search?id=510000003" \
  -H "Authorization: Bearer ak_…"

קריאה ושינוי של ההגדרות

curl -s https://makor.pro/api/v1/settings -H "Authorization: Bearer ak_…"

curl -s -X PATCH https://makor.pro/api/v1/settings \
  -H "Authorization: Bearer ak_…" \
  -H "Content-Type: application/json" \
  -d '{"check_registries": true, "store_results": false}'
תיעוד ה-API · Makor