דילוג לתוכן
thisverify
מפתחים

ThisVerify API

REST API פשוט: שולחים קובץ, מקבלים דוח JSON מלא.

סקירה

ה-API של ThisVerify מאפשר לשלוח מסמך (PDF או תמונה) ולקבל דוח זיוף מלא: ציון סיכון 0–100, החלטה (סיכון נמוך / לבדיקה / סיכון גבוה), ממצאים עם מיקום מדויק על המסמך, בדיקות חשבוניות ונתונים שחולצו. ה-API מבוסס REST, מחזיר JSON ועובד בצורה אסינכרונית: יוצרים בדיקה, ומקבלים את התוצאה ב-Webhook או בשליפה.

כתובת בסיס
https://thisverify-green.vercel.app/api/v1
גרסה
2026-10-01
פורמט
JSON · UTF-8 · HTTPS
  1. 1. שליחה
    POST /scans עם הקובץ. תשובה מיידית 202 עם מזהה בדיקה.
  2. 2. ניתוח
    המנועים רצים במקביל — לרוב 20–60 שניות.
  3. 3. תוצאה
    Webhook ‏scan.completed, או GET /scans/{id}.

אימות ומפתחות

כל בקשה נשלחת עם מפתח API בכותרת Authorization. המפתחות שייכים לארגון (לא למשתמש בודד), נוצרים במסך "API ואינטגרציות" באזור האישי, מוצגים פעם אחת בלבד ונשמרים אצלנו כגיבוב (hash) בלבד. אפשר להחזיק כמה מפתחות — למשל אחד לכל מערכת — ולבטל כל אחד בנפרד.

גישת API — בחבילות בתשלום

מפתחות API ו-Webhooks זמינים לארגונים בחבילה העסקית או הארגונית. התיעוד, הדוגמאות והמפרט פתוחים לכולם — אפשר לתכנן את החיבור כבר עכשיו. מפתח של ארגון בלי חבילה מתאימה יקבל 403 NO_API_ACCESS.

חבילות ומחירים
Authorization: Bearer tv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
אל תשלבו מפתח בקוד צד-לקוח (דפדפן/אפליקציה). קראו ל-API רק מהשרת שלכם.

הרשאות (Scopes)

לכל מפתח מוגדרות הרשאות. תנו לכל מערכת רק את מה שהיא צריכה.

שדהסוגתיאור
scans:writescopeיצירת בדיקות
scans:readscopeקריאת בדיקות ודוחות
scans:deletescopeמחיקת בדיקות
usage:readscopeקריאת שימוש ומכסה

התחלה מהירה

בדיקה ראשונה בשתי פקודות:

curl -X POST https://thisverify-green.vercel.app/api/v1/scans \
  -H "Authorization: Bearer $THISVERIFY_KEY" \
  -H "Idempotency-Key: loan-88231-doc-1" \
  -F "file=@transfer.pdf" \
  -F 'context={"document_type":"bank_transfer","expected_amount":"12500","expected_name":"ישראל ישראלי"}' \
  -F "client_reference=loan-88231"

# → 202 {"id":"8f1c…","object":"scan","status":"queued",…}

curl https://thisverify-green.vercel.app/api/v1/scans/8f1c… -H "Authorization: Bearer $THISVERIFY_KEY"

יצירת בדיקה

POST/api/v1/scans

שלוש דרכים לשלוח את הקובץ: multipart (מומלץ), JSON עם base64, או JSON עם כתובת https ציבורית שממנה נוריד את הקובץ. מחזיר 202 עם אובייקט הבדיקה בסטטוס queued. דורש scans:write. כל בדיקה מנכה אחת מהמכסה החודשית של הארגון; אם הניתוח נכשל אצלנו — הבדיקה מוחזרת למכסה.

שדהסוגתיאור
filebinaryהקובץ (multipart). PDF, ‏JPEG, ‏PNG, ‏WEBP או HEIC.
file.content_base64stringחלופה ב-JSON: תוכן הקובץ ב-base64 (אפשר גם data URL). עם file.name.
file_urlstringחלופה ב-JSON: כתובת https ציבורית. חייבת להחזיר את הקובץ תוך 15 שניות, ללא הפניות. כתובות פנימיות נחסמות.
context.document_typeenumרמז לסוג המסמך: bank_transfer, payment_app, bank_statement, account_confirmation, balance_confirmation, check, deposit_receipt, card_statement, payslip, invoice, tax_form, id_document, utility_bill, loan_document, medical, contract, other
context.expected_amountstringהסכום שאתם מצפים לראות. אי-התאמה תסומן כממצא.
context.expected_namestringשם המוטב/בעל החשבון/העובד הצפוי.
context.expected_dateYYYY-MM-DDהתאריך הצפוי.
context.expected_referencestringאסמכתא/מספר חשבון צפוי.
context.notesstringהקשר חופשי למנתח (עד 1,000 תווים).
client_referencestringהמזהה שלכם (מספר בקשה/תיק). חוזר בכל תשובה וב-Webhook, ואפשר לסנן לפיו.
metadataobjectעד 20 זוגות מפתח-ערך שלכם (ערכים עד 500 תווים). ב-multipart שולחים כמחרוזת JSON.
lang"he" | "en"שפת הדוח. ברירת מחדל: he.
JSON
POST /api/v1/scans
Content-Type: application/json
Idempotency-Key: 4c1f…

{
  "file": { "name": "payslip-06.pdf", "content_base64": "JVBERi0xLjcK…" },
  "context": { "document_type": "payslip", "expected_name": "Dana Levi" },
  "client_reference": "app-55102",
  "metadata": { "branch": "tel-aviv", "officer": "u-1182" },
  "lang": "en"
}

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

GET/api/v1/scans/{id}

מחזיר את הבדיקה. כשהסטטוס completed — כולל את הדוח המלא בשדה report. הוסיפו ?include=summary כדי לקבל רק תקציר (בלי report). דורש scans:read. בזמן עיבוד השדה stage מראה את השלב הנוכחי.

200 Response
{
  "id": "8f1c2a4e-…",
  "object": "scan",
  "status": "completed",
  "verdict": "high_risk",
  "risk_score": 91,
  "document_type": "bank_transfer",
  "issuer": "בנק הפועלים",
  "channel": "app_screenshot",
  "client_reference": "loan-88231",
  "report": {
    "summary": "…",
    "recommended_actions": ["…"],
    "findings": [
      {
        "id": "ai-1",
        "category": "visual",
        "severity": "high",
        "confidence": 0.93,
        "title": "Amount digits re-rendered",
        "detail": "The digits of the amount use a different font weight and anti-aliasing…",
        "box": { "page": 1, "box_2d": [412, 520, 446, 700] }
      }
    ],
    "checks": [ { "id": "arith", "label": "…", "status": "fail", "detail": "…" } ],
    "extracted": { "amounts": ["12,500.00"], "dates": ["2026-10-05"], "iban": "IL62…" },
    "forensic_analysis": { "pixel_variance": { "has_variance": true, "score": 0.88 } },
    "engine": { "version": "…", "duration_ms": 31244, "layers": ["pdf", "metadata", "ela", "content", "ai"] }
  }
}

box_2d הוא [ymin, xmin, ymax, xmax] בסקאלה 0–1000 יחסית לעמוד — כך אפשר לצייר את הסימון בכל רזולוציה.

רשימת בדיקות

GET/api/v1/scans

מהחדש לישן, עם עימוד מבוסס cursor. דורש scans:read.

שדהסוגתיאור
limit1–100מספר תוצאות בעמוד. ברירת מחדל 25.
cursorstringהערך next_cursor מהעמוד הקודם.
statusenumqueued · processing · completed · failed
verdictenumlow_risk · review · high_risk
client_referencestringסינון לפי המזהה שלכם.
created_after / created_beforeISO 8601טווח תאריכים.
{
  "object": "list",
  "data": [ { "id": "…", "object": "scan", "status": "completed", "verdict": "review", … } ],
  "has_more": true,
  "next_cursor": "eyJ0IjoiMjAyNi0xMC0w…"
}

מחיקת בדיקה

DELETE/api/v1/scans/{id}

מוחק לצמיתות את הבדיקה, הדוח וקובץ המקור (כולל עותקים שנאספו לאימון). דורש scans:delete. מתאים לבקשות מחיקה לפי חוק הגנת הפרטיות / GDPR.

שימוש ומכסה

GET/api/v1/usage

השימוש של הארגון בתקופה הנוכחית. דורש usage:read.

{
  "object": "usage",
  "plan": { "id": "business", "name": "Business" },
  "period": { "start": "2026-10-01T00:00:00.000Z", "end": "2026-11-01T00:00:00.000Z" },
  "used": 1840,
  "limit": 5000,
  "remaining": 3160,
  "total_scans": 22114
}

ולבדיקת מפתח: GET /api/v1 מחזיר את הארגון וההרשאות של המפתח.

Webhooks

במקום לשאול שוב ושוב — הגדירו כתובת https במסך "API ואינטגרציות", ואנחנו נשלח POST כשהבדיקה מסתיימת. לכל כתובת סוד חתימה משלה (whsec_…).

שדהסוגתיאור
scan.completedeventהבדיקה הסתיימה. כולל verdict, ‏risk_score, ‏client_reference ו-metadata. לדוח המלא — GET /scans/{id}.
scan.failedeventהבדיקה נכשלה (למשל קובץ פגום). היחידה הוחזרה למכסה.
pingeventאירוע בדיקה שנשלח מכפתור "שליחת בדיקה".
POST → your endpoint
ThisVerify-Event: scan.completed
ThisVerify-Delivery: 5b0e…            ← unique event id (dedupe on it)
ThisVerify-Signature: t=1791364364,v1=3f9a…

{
  "id": "5b0e…",
  "type": "scan.completed",
  "created": "2026-10-07T09:13:21.004Z",
  "data": {
    "scan": {
      "id": "8f1c…", "object": "scan", "status": "completed",
      "verdict": "high_risk", "risk_score": 91, "document_type": "bank_transfer",
      "client_reference": "loan-88231", "metadata": { "branch": "tel-aviv" },
      "file": { "name": "transfer.pdf", "sha256": "…" }
    }
  }
}
  • • החזירו 2xx תוך 10 שניות. עבודה כבדה — עשו ברקע אחרי שהחזרתם תשובה.
  • • ניסיונות חוזרים: מיד, אחרי 3 ו-10 שניות, ואז אחרי 1 דק׳, 5 דק׳, 30 דק׳, שעתיים ו-12 שעות.
  • • ייתכנו כפילויות — זהו אותן לפי ThisVerify-Delivery.
  • • אחרי 50 כשלונות רצופים הכתובת מושבתת אוטומטית; אפשר להפעיל מחדש מהמסך.

אימות חתימה

ודאו שכל בקשה הגיעה מאיתנו: חשבו HMAC-SHA256 על המחרוזת "{t}.{גוף הבקשה הגולמי}" עם סוד ה-Webhook, השוו ל-v1 בהשוואה בזמן קבוע, ודחו בקשות שה-t שלהן ישן מ-5 דקות.

import crypto from 'node:crypto';

export function verifyThisVerify(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  const a = Buffer.from(expected), b = Buffer.from(parts.v1 || '');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Express: app.post('/hooks/thisverify', express.raw({ type: 'application/json' }), (req, res) => {
//   if (!verifyThisVerify(req.body.toString(), req.get('ThisVerify-Signature'), process.env.TV_WHSEC)) return res.sendStatus(400);
//   res.sendStatus(200); queue.push(JSON.parse(req.body));
// });

אידמפוטנטיות

שלחו כותרת Idempotency-Key (עד 200 תווים, למשל מזהה המסמך אצלכם) בכל POST /scans. אם הבקשה נשלחת שוב עם אותו מפתח ואותו קובץ — תקבלו את אותה בדיקה (200 עם Idempotent-Replayed: true) בלי חיוב נוסף. אותו מפתח עם קובץ אחר מחזיר 409. המפתחות נשמרים 7 ימים.

מגבלות קצב

המגבלה היא לכל ארגון, לדקה (ברירת מחדל 120; בחבילות ארגוניות לפי הסכם). כל תשובה כוללת RateLimit-Limit, ‏RateLimit-Remaining ו-RateLimit-Reset. בחריגה — 429 עם Retry-After בשניות. גודל קובץ מרבי: 10MB.

שגיאות

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

HTTP/1.1 402 Payment Required
X-Request-Id: req_0c51d0a3e8b14f2a9d11

{ "error": { "code": "QUOTA_EXCEEDED", "message": "The organization has used its monthly allowance.", "request_id": "req_0c51d0a3e8b14f2a9d11" } }
HTTPcodeמשמעות
401NO_KEYMissing API key. Send "Authorization: Bearer tv_live_…".
401INVALIDThe API key is invalid or revoked.
403SUSPENDEDThe organization or key owner is suspended.
403NO_API_ACCESSAPI access requires a paid plan that includes the API (Business or Enterprise). Upgrade from the dashboard or contact sales.
403INSUFFICIENT_SCOPEThe API key does not have the required scope.
429RATE_LIMITEDToo many requests. Retry after the time in the Retry-After header.
400INVALID_REQUESTThe request is malformed.
400FILE_REQUIREDProvide a file as multipart "file", JSON "file.content_base64", or JSON "file_url".
400EMPTY_FILEThe file is empty.
413FILE_TOO_LARGEThe file exceeds the size limit.
415UNSUPPORTED_FILEUnsupported file type. Use PDF, JPEG, PNG, WEBP or HEIC.
400FILE_URL_REJECTEDfile_url must be a public https URL that returns the file within 15 seconds.
402QUOTA_EXCEEDEDThe organization has used its monthly allowance.
503AI_NOT_CONFIGUREDThe analysis service is temporarily unavailable.
404NOT_FOUNDResource not found.
409CONFLICTAn Idempotency-Key was reused with a different request.
500SERVICE_ERRORUnexpected error. Retry with the same Idempotency-Key.

אובייקט הבדיקה

שדהסוגתיאור
statusenumqueued → processing → completed / failed
verdictenumlow_risk — לא נמצאו סימני זיוף משמעותיים · review — נדרשת בדיקה אנושית · high_risk — סימני זיוף מובהקים
risk_score0–100ציון משוקלל מכל שכבות הבדיקה.
document_type / issuer / channelstringסוג המסמך, הגוף המנפיק (בנק/מעסיק/קופה) ומקור הקובץ (PDF מקורי, צילום מסך, צילום נייר…).
report.findings[]arrayממצאים: category, ‏severity ‏(info/low/medium/high/critical), ‏confidence ‏(0–1), כותרת, פירוט ו-box.
report.checks[]arrayבדיקות דטרמיניסטיות: חשבון, יתרות, מע״מ, IBAN, ספרת ביקורת ת״ז, קוד בנק, יום בשבוע ועוד — pass/warn/fail.
report.extractedobjectנתונים שחולצו: סכומים, תאריכים, שמות, חשבונות, תנועות.
labelenum | nullתיוג אנושי שלכם (genuine/fraud), אם סומן בממשק.

OpenAPI

המפרט המלא בפורמט OpenAPI 3.1 — לייבוא ל-Postman, ‏Insomnia או לייצור SDK בכל שפה.