DCM Extraction API
חוזה נכנס — 53 שדות יוצאים
שולחים קובץ חוזה — PDF, Word או סריקה — ומקבלים JSON עם הצדדים, התאריכים, הסכומים, ההצמדה והנכס, כל שדה עם ציטוט המקור שלו מגוף החוזה. בלי מודל לאמן ובלי ממשק ללמוד: שתי קריאות HTTP.
איך זה עובד
ה-API הוא אסינכרוני: העלאה מחזירה מזהה ג׳וב מיד, והתוצאה נאספת בקריאת GET. אין Webhook — לולאת polling פשוטה מספיקה.
שולחים את הקובץ
POST /jobs עם הקובץ כ-multipart. התשובה היא 202 עם jobId ו-pollUrl — עוד לפני שהעיבוד התחיל.
מחכים לעיבוד
הקובץ מומר ל-PDF, עובר OCR במידת הצורך ומנותח. שואלים GET /jobs/{id} כל pollAfterSeconds (5) שניות.
קוראים את ה-JSON
status = succeeded: 53 שדות ב-fields, ציטוטים ב-sources ונתוני איכות ב-meta. status = failed: error.code — וללא חיוב.
משלמים רק על מה שהצליח
מחיר לחילוץ מוצלח
$4.90
חיוב חודשי בשקלים · שער יציג של בנק ישראל · בתוספת מע"מ
ג׳וב שנכשל — חינם
ג׳וב שנכשל — מכל סיבה, כולל תקלה אצלנו — לא מחויב. מחויבים רק ג׳ובים שהסתיימו ב-status = succeeded.
חיוב חודשי מרוכז: סביב ה-10 בכל חודש מחויבות כל הקריאות המוצלחות שהושלמו בחודש הקלנדרי הקודם — חיוב אחד, חשבונית מס אחת.
הסכום בשקלים = מספר הקריאות × $4.90 × השער היציג של בנק ישראל ביום החיוב, בתוספת מע"מ. השער ששימש מופיע בחשבונית.
המחיר שהיה בתוקף כשהג׳וב הושלם הוא המחיר שמחויב — שינוי מחיר עתידי לא נוגע בג׳ובים שכבר הסתיימו.
מסגרת אשראי: עד $500 של שימוש שטרם שולם (ברירת מחדל, ניתן להגדלה). מעבר לכך POST /jobs מחזיר 402 credit_limit_reached עד שהחיוב החודשי נגבה; קריאות GET ממשיכות לעבוד.
אמצעי התשלום נקלט פעם אחת יחד עם הצוות שלנו. אנחנו שומרים רק טוקן סליקה ו-4 ספרות אחרונות — אף פעם לא את מספר הכרטיס.
מפתח API בכל קריאה
המפתח מתחיל ב-dcm_live_ ומועבר באחת משתי כותרות — שתיהן שקולות. אין OAuth, אין טוקנים מתחלפים.
Authorization: Bearer dcm_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0
# or, equivalently
X-API-Key: dcm_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0הנפקה וניהול
מפתחות מונפקים על ידי הצוות שלנו לכל חשבון (עד 5 מפתחות פעילים) ומוצגים פעם אחת בלבד — שמרו אותם במנהל סודות, לא בקוד ולא ב-git. הקידומת (12 התווים הראשונים) מופיעה ב-GET /me כדי שתדעו איזה מפתח בשימוש. מפתח שנחשף? נבטל אותו וננפיק חדש מיד.
שרת-לשרת בלבד
ה-API אינו מיועד לדפדפן: אין רשימת CORS למקורות לקוח, ולכן fetch מדף אינטרנט ייכשל ב-preflight. זה מכוון — מפתח שמוטמע בדפדפן הוא מפתח ציבורי. קראו ל-API מהשרת שלכם. אימות שנכשל יותר מ-50 פעמים בדקה מאותה כתובת IP מחזיר 429 too_many_auth_failures.
שתי קריאות ואתם בפנים
שולחים קובץ, שואלים מה קרה. זה כל הפרוטוקול. החליפו dcm_live_YOUR_KEY במפתח שלכם.
1העלאה — מחזירה 202 עם jobId
curl -X POST "https://dcm-api-461123279240.me-west1.run.app/api/v1/extract/jobs" \
-H "Authorization: Bearer dcm_live_YOUR_KEY" \
-H "Idempotency-Key: lease-2024-0417" \
-F "file=@lease.pdf" \
-F 'our_party=א.ב. נכסים בע"מ' \
-F "reference=lease-2024-0417"{
"jobId": "8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"status": "queued",
"createdAt": "2026-10-12T08:41:07.512345+00:00",
"reference": "lease-2024-0417",
"pollUrl": "/api/v1/extract/jobs/8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"pollAfterSeconds": 5
}2polling — כל pollAfterSeconds (5) שניות, עד ש-status הוא succeeded או failed
curl "https://dcm-api-461123279240.me-west1.run.app/api/v1/extract/jobs/8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f" \
-H "Authorization: Bearer dcm_live_YOUR_KEY"3התוצאה — fields, sources, meta
{
"jobId": "8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"status": "succeeded",
"fields": {
"counterparty_name": "א.ב. סחר ושירותים בע\"מ",
"our_role": "landlord",
"signed_date": "2024-03-14",
"expiry_date": "2029-03-31",
"monthly_rent_agorot": 4200000
},
"sources": {
"monthly_rent": "דמי השכירות החודשיים יעמדו על סך של 42,000 ₪ בתוספת מע\"מ כדין"
},
"meta": {
"schemaVersion": "2026-10",
"fieldCount": 53,
"extractionConfidence": {
"money": "high",
"parties": "high",
"dates": "high",
"terms": "medium",
"asset": "high"
},
"durationMs": 48210,
"ourRoleSource": "our_party"
}
}הדוגמה מקוצרת; התשובה המלאה מופיעה ב-נקודות קצה והקוד המלא בשלוש שפות ב-דוגמאות קוד.
נקודות קצה
כל הנתיבים יחסיים ל-Base URL. תשובות הצלחה הן JSON ב-camelCase; מפתחות השדות בתוך fields נשארים snake_case כפי שהם בקטלוג.
https://dcm-api-461123279240.me-west1.run.app/api/v1/extract/jobsשליחת חוזה לחילוץבקשת multipart/form-data. הבדיקות הזולות (שם קובץ, סיומת, גודל מוצהר) רצות לפני קריאת הגוף; אחר כך נתפס "מקום" בחשבון, ורק אז הקובץ נקרא, מאומת, מומר ל-PDF ונספר. כל כשל אחרי תפיסת המקום יוצר ג׳וב במצב failed שתראו ב-GET /jobs — חינם.
| פרמטר | היכן | סוג | תיאור |
|---|---|---|---|
fileחובה | multipart | file | .pdf .doc .docx .png .jpg .jpeg .heic .heif · עד 30 MB · עד 150 עמודים. התוכן נבדק (magic bytes), לא רק הסיומת. |
our_partyאופציונלי | multipart | string ≤ 200 | השם המשפטי שלכם בדיוק כפי שמודפס בחוזה. קובע את our_role ואת זהות הצד השני — ראו הטיפ למטה. |
referenceאופציונלי | multipart | string ≤ 120 | מזהה חופשי שלכם (מספר מסמך, מזהה במערכת). מוחזר כ-reference בכל תשובה. |
Idempotency-Keyאופציונלי | header | string ≤ 120 | מפתח ייחודי לכל מסמך, תחום לחשבון שלכם. שליחה חוזרת עם אותו מפתח מחזירה את המעטפה של הג׳וב הקיים (jobId, status, pollUrl; קוד 202 בזמן ריצה, 200 כשהסתיים) בלי ג׳וב כפול ובלי חיוב כפול. את התוצאה קוראים תמיד ב-GET. ג׳וב שנכשל (או נמחק אחרי 30 יום) משחרר את המפתח: שליחה חוזרת איתו יוצרת ג׳וב חדש, וזה הניסיון החוזר שקודי השגיאה ממליצים עליו. |
curl -X POST "https://dcm-api-461123279240.me-west1.run.app/api/v1/extract/jobs" \
-H "Authorization: Bearer dcm_live_YOUR_KEY" \
-H "Idempotency-Key: lease-2024-0417" \
-F "file=@lease.pdf" \
-F 'our_party=א.ב. נכסים בע"מ' \
-F "reference=lease-2024-0417"{
"jobId": "8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"status": "queued",
"createdAt": "2026-10-12T08:41:07.512345+00:00",
"reference": "lease-2024-0417",
"pollUrl": "/api/v1/extract/jobs/8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"pollAfterSeconds": 5
}pollUrl הוא נתיב יחסי למקור ה-API. pollAfterSeconds הוא המרווח המומלץ בין קריאות polling.
/jobs/{jobId}מצב ג׳וב ותוצאההמעטפה זהה בכל מצב; מה שמשתנה הוא אילו מפתחות קיימים: pollAfterSeconds רק כל עוד הג׳וב queued או processing, fields / sources / meta רק ב-succeeded, error רק ב-failed. startedAt, completedAt ו-expiresAt הם null עד שקורים.
{
"jobId": "8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"status": "queued",
"createdAt": "2026-10-12T08:41:07.512345+00:00",
"startedAt": null,
"completedAt": null,
"expiresAt": null,
"reference": "lease-2024-0417",
"ourParty": "א.ב. נכסים בע\"מ",
"file": {
"name": "lease.pdf",
"sizeBytes": 1843201,
"pages": null,
"language": null
},
"pollAfterSeconds": 5
}meta.ourRoleSourceמסביר מאיפה הגיע our_role:"our_party"(מהרמז ששלחתם),"counterparty_label"(הוסק מהתוויות בחוזה) אוnull.file.pagesהוא מספר עמודי התוכן אחרי סינון עמודים ריקים — זהה ל-fields.page_count.- ג׳וב שנתקע (processing מעל 45 דקות, queued מעל 60) מסומן failed עם timeout בקריאת ה-GET הבאה. חינם.
/jobs?limit=20הג׳ובים האחרוניםהחדשים ראשונים. limit עד 100 (ברירת מחדל 20). ג׳ובים שנמחקו נשארים ברשימה עם purged: true — התוצאה שלהם כבר לא זמינה.
{
"jobs": [
{
"jobId": "8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f",
"status": "succeeded",
"createdAt": "2026-10-12T08:41:07.512345+00:00",
"completedAt": "2026-10-12T08:41:57.314876+00:00",
"file": {
"name": "lease.pdf",
"pages": 24
},
"reference": "lease-2024-0417",
"purged": false
},
{
"jobId": "c0a8e2d1-7f3b-4e9a-8d21-5b6c7d8e9f01",
"status": "failed",
"createdAt": "2026-10-12T09:02:11.004512+00:00",
"completedAt": "2026-10-12T09:02:19.871003+00:00",
"file": {
"name": "scan.pdf",
"pages": 3
},
"reference": "scan-0099",
"purged": false
}
]
}/fieldsקטלוג השדותמחזיר את 53 השדות בסדר שבו הם מופיעים ב-fields, עם סוג, קבוצה, תוויות ותיאורים בעברית ובאנגלית — אותו קטלוג שמופיע בטבלה למטה. שימושי לבניית מיפוי אוטומטי או ממשק הצגה.
{
"schemaVersion": "2026-10",
"fields": [
{
"key": "title_he",
"type": "string",
"group": "identity",
"labelHe": "כותרת (עברית)",
"labelEn": "Title (Hebrew)",
"descriptionHe": "כותרת החוזה כפי שמופיעה במסמך; אם אין כותרת — שם הקובץ ללא סיומת.",
"descriptionEn": "The contract's title as printed in the document; falls back to the file name without its extension."
},
{
"key": "title_en",
"type": "string",
"group": "identity",
"labelHe": "כותרת (אנגלית)",
"labelEn": "Title (English)",
"descriptionHe": "כותרת באנגלית, רק אם המסמך עצמו כולל כותרת באנגלית (לא תרגום).",
"descriptionEn": "English title only when the document itself carries one (never a translation)."
}
]
}/meהחשבון, השימוש והמגבלותמה שבתוקף לחשבון שלכם: usage.dueNextCharge הן קריאות מוצלחות שיחויבו בחיוב הבא, accruingThisMonth הן קריאות החודש הנוכחי, ו-uncollectedUsdCents הוא הסכום הפתוח בסנטים. limits הם הערכים שנאכפים בפועל — אם הגדלנו לכם מסגרת, תראו זאת כאן.
{
"customer": {
"name": "A.B. Properties Ltd",
"nameHe": "א.ב. נכסים בע\"מ"
},
"keyPrefix": "dcm_live_a1B",
"usage": {
"monthSucceeded": 30,
"monthFailed": 1,
"inflight": 2,
"dueNextCharge": 60,
"accruingThisMonth": 30,
"uncollectedUsdCents": 44100
},
"limits": {
"maxInflightJobs": 10,
"maxFileBytes": 31457280,
"maxPages": 150,
"maxFailedJobsPerDay": 50,
"creditLimitUsdCents": 50000,
"retentionDays": 30,
"supportedExtensions": [
".pdf",
".doc",
".docx",
".png",
".jpg",
".jpeg",
".heic",
".heif"
]
},
"pricing": {
"usdCentsPerSuccessfulJob": 490,
"billing": "monthly",
"currency": "ILS at Bank of Israel rate + VAT"
}
}מחזור חיי ג׳וב
ארבעה מצבים, שני סופיים. אחרי תקופת השמירה הקובץ והתוצאה נמחקים — רשומת הג׳וב נשארת.
queuedבתור
POST חזר 202. הג׳וב מחכה לעובד.
processingבעיבוד
המרה, OCR, ניתוח. startedAt נקבע.
succeededהצליח
fields · sources · meta. מחויב $4.90.
failedנכשל
error.code + message. לא מחויב.
purgedנמחק
הקובץ וה-JSON נמחקו. GET מחזיר 410 job_expired.
ג׳וב queued או processing נושא pollAfterSeconds; ג׳וב במצב סופי לא. בכל מצב, expiresAt (completedAt + 30 יום) אומר מתי המחיקה תתבצע.
טיפ: שלחו our_party
השם המשפטי שלכם בדיוק כפי שמודפס בחוזה — כולל "בע"מ" והניקוד של ראשי התיבות — משפר משמעותית את our_role ואת זיהוי הצד השני. עם הרמז, ה-API יודע מי "אנחנו" ומחזיר את הצד השני ב-counterparty_*; בלעדיו הוא מסיק מתוויות כמו "השוכר" / "המשכיר", ובמקרה של ספק מחזיר our_role = null במקום לנחש.
53 השדות
כל שדה תמיד קיים בתשובה, בסדר הזה. ערך שלא נמצא במסמך הוא null — לא מחרוזת ריקה, לא 0. הקטלוג זמין גם ב-GET /fields.
סוגי ערכים
ערכי enum
type—lease | contracting | subcontract | real_estate | consulting | supply | management· סוג החוזהour_role—tenant | landlord | manager· התפקיד של our_party; null כשלא ניתן לקבועproperty_type—commercial | mall | street_shop | office | warehouse | parking_lot | industrial | residential | land | other· סוג הנכסrisk_level—low | medium | high· הערכה עצמית של מנוע החילוץ בלבדזיהוי החוזה
Identityidentity· 6title_hestringכותרת (עברית) · Title (Hebrew)
כותרת החוזה כפי שמופיעה במסמך; אם אין כותרת — שם הקובץ ללא סיומת.
title_enstringכותרת (אנגלית) · Title (English)
כותרת באנגלית, רק אם המסמך עצמו כולל כותרת באנגלית (לא תרגום).
typeenumסוג חוזה · Contract type
אחד מ: lease | contracting | subcontract | real_estate | consulting | supply | management.
type_label_hestringסוג חוזה (תווית) · Contract type (Hebrew label)
תווית עברית של סוג החוזה, למשל "שכירות".
language_detectedstringשפת המסמך · Detected language
שפת הטקסט שזוהתה: he | en | mixed.
page_countintegerמספר עמודים · Page count
מספר עמודי התוכן לאחר סינון עמודים ריקים — עשוי להיות נמוך ממספר העמודים בקובץ.
צדדים
Partiesparties· 9counterparty_namestringשם הצד השני · Counterparty name
השם המשפטי המלא של הצד השני כפי שמופיע בחוזה (יחסית ל-our_party כשנמסר).
counterparty_id_numberstringח.פ. / ת.ז. הצד השני · Counterparty ID number
מספר ח.פ. / ע.מ. / ת.ז. של הצד השני, ספרות בלבד.
counterparty_typestringסוג הצד השני · Counterparty type
company | individual — על פי המסמך.
entity_typestringסוג ישות משפטית · Legal entity type
צורת ההתאגדות של הצד השני: בע״מ / שותפות / עוסק מורשה / עמותה / אגודה שיתופית / private_individual / other.
our_roleenumהתפקיד שלנו · Our role
tenant | landlord | manager | null — תפקידו של our_party בחוזה (כשנמסר); null כשלא ניתן לקבוע.
contact_namestringאיש קשר · Contact name
איש הקשר בצד השני כפי שמופיע בחוזה.
contact_phonestringטלפון איש קשר · Contact phone
טלפון איש הקשר כפי שמופיע בחוזה.
contact_emailstringדוא"ל איש קשר · Contact email
כתובת הדוא"ל של איש הקשר כפי שמופיעה בחוזה.
activity_typestringסוג פעילות · Activity type
תחום הפעילות של השוכר/הצד השני בנכס (טקסט חופשי, למשל "מסעדנות").
תאריכים ותקופה
Dates & termdates_term· 11signed_datedateתאריך חתימה · Signed date
תאריך החתימה על החוזה. מחרוזת ISO; עשויה להיות חלקית ("2023-04" / "2023").
expiry_datedateתאריך סיום · Expiry date
תאריך סיום החוזה (ללא מימוש אופציות). מחרוזת ISO; עשויה להיות חלקית ("2023-04" / "2023").
lease_start_datedateתחילת השכירות · Lease start date
תחילת תקופת השכירות לפי גוף החוזה; כשאין תאריך תחילה מפורש הערך זהה ל-signed_date. מחרוזת ISO; עשויה להיות חלקית ("2023-04" / "2023").
lease_end_initialdateסיום התקופה הראשונית · Initial term end
סיום תקופת השכירות הראשונית (לפני אופציות); כשלא צוין — זהה ל-expiry_date. מחרוזת ISO; עשויה להיות חלקית ("2023-04" / "2023").
term_monthsintegerתקופה (חודשים) · Term (months)
אורך התקופה הראשונית בחודשים.
option_monthsintegerאופציה (חודשים) · Option (months)
אורך תקופת אופציה אחת בחודשים.
option_countintegerמספר אופציות · Option count
מספר תקופות האופציה שהחוזה מעניק.
lease_optionslistאופציות · Lease options
רשימת אופציות: [{start, end, notice_required_days, conditions, source}].
notice_period_daysintegerתקופת הודעה (ימים) · Notice period (days)
ימי ההודעה המוקדמת הנדרשים לסיום / אי-חידוש.
early_exit_penaltystringקנס יציאה מוקדמת · Early exit penalty
תיאור טקסטואלי של הקנס על יציאה מוקדמת (למשל "3 חודשי שכירות").
early_termination_fee_agorotmoney_agorotדמי יציאה מוקדמת · Early termination fee
דמי היציאה המוקדמת כסכום, כשהם ניתנים לכימות. סכום באגורות (₪1 = 100).
כסף
Moneymoney· 10value_amount_agorotmoney_agorotשווי החוזה · Contract value
שווי כולל של החוזה לתקופה הראשונית (למשל שכ"ד חודשי × חודשים, או סכום מדרגות השכירות). סכום באגורות (₪1 = 100).
monthly_rent_agorotmoney_agorotשכר דירה חודשי · Monthly rent
שכר הדירה החודשי הכולל (סכום כל הרכיבים ב-monthly_rent_components), ללא מע"מ. סכום באגורות (₪1 = 100).
monthly_rent_componentslistרכיבי שכר הדירה · Monthly rent components
פירוט רכיבי החודש: [{label, amount_agorot, source}] — משרדים, חניות, ציוד וכו'.
annual_rent_agorotmoney_agorotשכר דירה שנתי · Annual rent
שכר הדירה השנתי (monthly_rent_agorot × 12 אלא אם החוזה נוקב בסכום שנתי). סכום באגורות (₪1 = 100).
rent_schedulelistמדרגות שכירות · Rent schedule
שכירות מדורגת לאורך התקופה: [{start_month, end_month, monthly_agorot, source}].
revenue_guaranteeslistתקבולים מובטחים · Revenue guarantees
רצפות הכנסה נפרדות משכר הדירה: [{label, monthly_minimum_agorot, formula, source}].
security_typestringסוג ביטחונות · Security type
סוגי הביטחונות הנדרשים, למשל "ערבות בנקאית", "שטר חוב + ערבות אישית".
security_amount_agorotmoney_agorotסכום הביטחונות · Security amount
סכום הביטחונות הכולל. סכום באגורות (₪1 = 100).
management_fee_agorotmoney_agorotדמי ניהול · Management fee
דמי הניהול החודשיים, כשנקובים בסכום. סכום באגורות (₪1 = 100).
rent_increase_pctnumberעליית שכר דירה (%) · Rent increase (%)
אחוז עליית שכר הדירה הקבוע בחוזה (למשל 3.0), כשאינו הצמדה למדד.
הצמדה
Indexationindexation· 3base_cpi_datedateמדד בסיס · Base CPI month
חודש מדד הבסיס להצמדה (YYYY-MM); בחוזים צמודי מדד ללא מדד בסיס מפורש — ברירת מחדל: חודש החתימה.
indexation_mechanismstringמנגנון הצמדה · Indexation mechanism
תיאור מנגנון ההצמדה כפי שמופיע בחוזה (למשל "הצמדה למדד המחירים לצרכן").
cpi_indexationobjectהצמדה (מובנה) · Indexation (structured)
{type: cpi|usd|fixed_pct|none, frequency, base_date, floor_pct, ceiling_pct, source}.
הנכס
Assetasset· 12citystringעיר · City
העיר שבה נמצא הנכס.
regionstringאזור · Region
אזור בארץ (מרכז / צפון / שרון / דרום / ירושלים וכו').
addressstringכתובת · Address
כתובת הנכס (רחוב ומספר) כפי שמופיעה בחוזה.
area_sqmnumberשטח (מ"ר) · Area (sqm)
שטח הנכס במ"ר (ברוטו, כפי שנקוב בחוזה).
floorstringקומה · Floor
הקומה (טקסט — למשל "5", "קרקע", "-1").
unit_numberstringמספר יחידה · Unit number
מספר היחידה / החנות / המשרד.
gushstringגוש · Gush (block)
מספר גוש ברישום המקרקעין.
helkastringחלקה · Helka (parcel)
מספר חלקה ברישום המקרקעין.
tat_helkastringתת-חלקה · Tat-helka (sub-parcel)
מספר תת-חלקה ברישום המקרקעין.
property_typeenumסוג נכס · Property type
אחד מ: commercial | mall | street_shop | office | warehouse | parking_lot | industrial | residential | land | other.
parking_infostringחניה (תיאור) · Parking (description)
תיאור חופשי של החניות (למשל "2 חניות שמורות במרתף").
parking_spotsintegerמספר חניות · Parking spots
מספר החניות הכלולות בחוזה.
איכות החילוץ
Extraction qualityquality· 2risk_levelenumרמת סיכון · Risk level
low | medium | high | null — הערכה עצמית של מנוע החילוץ בלבד, לא ניתוח סיכונים מלא.
extraction_confidenceobjectביטחון החילוץ · Extraction confidence
{money, parties, dates, terms, asset} — כל אחד high | medium | low.
ציטוטי מקור — sources
לכל ערך מספרי או תאריך מהותי מצורף הציטוט מגוף החוזה שממנו הוא חולץ. זה מה שמאפשר לאמת שדה בשניות במקום לקרוא 40 עמודים.
sources הוא אובייקט שטוח: מפתח ← ציטוט מילולי. המפתחות הם שמות הראיות של מנוע החילוץ — בדרך כלל שם השדה ללא הסיומת _agorot (monthly_rent, value_amount) או שם השדה עצמו (signed_date, expiry_date, counterparty_name). התייחסו לקבוצת המפתחות כפתוחה; היא עשויה להיות ריקה ({}) כשלא נמצאו ציטוטים.
בנוסף, רשימות ואובייקטים מובנים (lease_options, monthly_rent_components, rent_schedule, cpi_indexation…) נושאים source פנימי לכל פריט — הפניה לסעיף או ציטוט.
הציטוטים הם מהטקסט כפי שזוהה (OCR כשצריך), ולכן עשויים לכלול שגיאות סריקה. הם מיועדים לאימות אנושי, לא לפענוח אוטומטי.
{
"sources": {
"counterparty_name": "בין: א.ב. סחר ושירותים בע\"מ, ח.פ. 515123456 (להלן: \"השוכר\")",
"signed_date": "נחתם בתל אביב ביום 14 במרץ 2024",
"expiry_date": "תקופת השכירות תסתיים ביום 31.3.2029",
"monthly_rent": "דמי השכירות החודשיים יעמדו על סך של 42,000 ₪ בתוספת מע\"מ כדין",
"value_amount": "סך דמי השכירות לתקופת השכירות: 2,520,000 ₪ בתוספת מע\"מ"
}
}שגיאות
כל שגיאה היא גוף JSON שטוח עם error ו-message — בלי עטיפת detail. הסתעפו לפי error; message נועד ללוגים ועשוי להשתנות. כמה שגיאות מוסיפות מפתחות (supported, maxBytes, retryAfter, details, jobId / status / purgedAt) — הן מפורטות בעמודת error בטבלה.
HTTP/1.1 429 Too Many Requests
Retry-After: 30
{
"error": "too_many_inflight_jobs",
"message": "10 jobs are already queued or processing; the limit is 10. Poll them to completion or retry in 30 seconds.",
"retryAfter": 30,
"maxInflightJobs": 10
}{
"error": "unsupported_file_type",
"message": "Unsupported file type .zip.",
"supported": [
".pdf",
".doc",
".docx",
".png",
".jpg",
".jpeg",
".heic",
".heif"
]
}{
"error": "file_too_large",
"message": "The file exceeds the 31457280 byte limit.",
"maxBytes": 31457280
}{
"error": "validation_error",
"message": "body.file: Field required",
"details": [
{
"type": "missing",
"loc": [
"body",
"file"
],
"msg": "Field required",
"input": null
}
]
}קודי שגיאה של HTTP
| HTTP | error | היכן | מתי |
|---|---|---|---|
| 401 | missing_api_key | כל קריאה | אין כותרת Authorization: Bearer או X-API-Key. |
| 401 | invalid_api_key | כל קריאה | המפתח לא מוכר, בוטל, או אינו מתחיל ב-dcm_. |
| 429 | too_many_auth_failures+ retryAfter | כל קריאה | יותר מ-50 אימותים כושלים בדקה מאותה כתובת IP. המתינו דקה (כותרת Retry-After: 60). |
| 403 | account_deactivated | כל קריאה | החשבון הושבת. פנו אלינו. |
| 403 | api_not_enabled | כל קריאה | המפתח שייך לחשבון ללא תוכנית API. |
| 402 | account_blocked | כל קריאה | חיוב חודשי נכשל ותקופת החסד חלפה. פנו לתמיכה לעדכון הכרטיס. |
| 402 | payment_method_required | כל קריאה | אין כרטיס אשראי בחשבון (משנאכפת קליטת כרטיס). |
| 402 | credit_limit_reached+ uncollectedUsdCents, creditLimitUsdCents | POST /jobs | שימוש מוצלח שטרם שולם הגיע למסגרת האשראי ($500 כברירת מחדל). GET ממשיך לעבוד; משתחרר כשהחיוב החודשי נגבה. |
| 400 | invalid_filename | POST /jobs | לקובץ אין שם, או ששמו ארוך מ-255 בתים. |
| 400 | client_disconnected | POST /jobs | החיבור נותק לפני שההעלאה הושלמה. לא נוצר ג׳וב; שלחו שוב. |
| 415 | unsupported_file_type+ supported | POST /jobs | סיומת או תוכן שאינם ברשימת הפורמטים הנתמכים. |
| 413 | file_too_large+ maxBytes | POST /jobs | הקובץ גדול מ-30 MB (לפי Content-Length או בפועל). |
| 422 | invalid_file | POST /jobs | התוכן אינו מסמך תקין (למשל docx שמתפרש ליותר מ-200 MB). |
| 422 | image_too_large+ maxPixels | POST /jobs | תמונה מעל 40 מגה-פיקסל. |
| 422 | conversion_failed | POST /jobs | ההמרה ל-PDF נכשלה (doc / docx / תמונה פגומים). |
| 422 | too_many_pages+ pages, maxPages | POST /jobs | יותר מ-150 עמודים. |
| 422 | validation_error+ details | כל קריאה | בקשה לא תקינה — למשל file חסר או reference ארוך מדי. details מפרט את השדות. |
| 429 | too_many_inflight_jobs+ retryAfter, maxInflightJobs | POST /jobs | 10 ג׳ובים כבר בתור או בעיבוד. מגיע עם כותרת Retry-After: 30. |
| 429 | too_many_failed_jobs+ retryAfter, maxFailedJobsPerDay | POST /jobs | 50 ג׳ובים נכשלו היום (יום קלנדרי בישראל). מתאפס בחצות; כותרת Retry-After נוקבת בשניות שנותרו. |
| 404 | job_not_found | GET /jobs/{id} | מזהה לא מוכר, UUID לא תקין, או ג׳וב של חשבון אחר. |
| 410 | job_expired+ jobId, status, purgedAt | GET /jobs/{id} | הקובץ והתוצאה נמחקו אחרי 30 יום. הגוף כולל את jobId, ה-status המקורי ו-purgedAt. |
| 500 | customer_misconfigured | POST /jobs | הגדרת החשבון חסרה. פנו אלינו — הג׳וב סומן ככשל (חינם). |
| 503 | queue_unavailable | POST /jobs | הג׳וב לא נכנס לתור העיבוד וסומן ככשל (חינם). נסו שוב. |
| 503 | storage_unavailable | POST /jobs | הקובץ לא נשמר באחסון והג׳וב סומן ככשל (חינם). נסו שוב בעוד רגע. |
| 503 | service_unavailable | כל קריאה | תקלת מסד נתונים זמנית. נסו שוב בעוד רגע. |
| 500 | internal_error | כל קריאה | שגיאה לא צפויה. נסו שוב; אם חוזר — פנו אלינו. |
קודי כשל של ג׳וב — error.code
מופיעים ב-GET /jobs/{id} כשהג׳וב הסתיים ב-failed. אף אחד מהם אינו מחויב.
conversion_failedההמרה ל-PDF נכשלה.
too_many_pagesיותר מ-150 עמודים.
invalid_fileהתוכן אינו תואם לסיומת, הקובץ פגום, או תמונה מעל 40 מגה-פיקסל.
ocr_emptyלא נמצא טקסט קריא — סריקה ריקה או באיכות נמוכה מדי.
ocr_failedזיהוי הטקסט (OCR) לא הושלם — לרוב עומס זמני. שלחו שוב בעוד כמה דקות; אם זה חוזר — פנו אלינו.
extraction_failedניתוח ה-AI לא הושלם. שלחו שוב.
extraction_emptyלא חולץ אף שדה מהותי — ככל הנראה המסמך אינו חוזה.
timeoutהעיבוד חרג ממגבלת הזמן.
internal_errorכשל פנימי בעיבוד. שלחו שוב.
מגבלות ושמירת נתונים
ברירות המחדל לכל חשבון. הערכים בתוקף עבורכם מוחזרים ב-GET /me — ואפשר לדבר איתנו על הגדלה.
30 MB
31,457,280 bytes
150
עמודים פיזיים בקובץ, לפני סינון
10
queued + processing
50
יום קלנדרי בישראל
30
ואז 410 job_expired
$500
שימוש שטרם שולם
פורמטים נתמכים
PDF (דיגיטלי או סרוק), Word (.doc / .docx) ותמונות (.png / .jpg / .jpeg / .heic / .heif). הכול מומר ל-PDF אחד לפני הניתוח; תמונות מוגבלות ל-40 מגה-פיקסל. הסיומת חייבת להתאים לתוכן.
שמירה ומחיקה
30 יום אחרי סיום הג׳וב — מוצלח או כושל — הקובץ המקורי, ה-PDF המומר וה-JSON נמחקים אוטומטית. רשומת הג׳וב (מזהה, סטטוס, תאריכים, reference) נשארת, ו-GET /jobs/{id} מחזיר 410 job_expired. שמרו את התוצאה אצלכם ברגע שהיא מתקבלת; אין "שחזור" אחרי המחיקה.
דוגמאות קוד
שליחה, polling וקריאת התוצאה — מקצה לקצה, כולל טיפול בשגיאות וב-410. ללא תלויות מעבר ל-requests ב-Python ו-fetch מובנה ב-Node 18+.
# 1. Submit — returns 202 with a jobId
curl -X POST "https://dcm-api-461123279240.me-west1.run.app/api/v1/extract/jobs" \
-H "Authorization: Bearer dcm_live_YOUR_KEY" \
-H "Idempotency-Key: lease-2024-0417" \
-F "file=@lease.pdf" \
-F 'our_party=א.ב. נכסים בע"מ' \
-F "reference=lease-2024-0417"
# 2. Poll every pollAfterSeconds (5s) until status is "succeeded" or "failed"
curl "https://dcm-api-461123279240.me-west1.run.app/api/v1/extract/jobs/8f1c2d3e-4b5a-4c6d-9e7f-0a1b2c3d4e5f" \
-H "Authorization: Bearer dcm_live_YOUR_KEY"
# 3. Shekels = agorot / 100
# .fields.monthly_rent_agorot → 4200000 → ₪42,000שאלות נפוצות
מוכנים לחבר?
ספרו לנו על נפח החוזים ועל המערכת שתקרא ל-API. נפתח חשבון, ננפיק מפתח ונלווה את החיבור הראשון.