REST API · v1

תיעוד ה-API

חברו את EASY2SIGN ל-CRM, למערכת הנהלת החשבונות או לאתר: צרו מסמכים מתבניות, שלחו לחתימה בוואטסאפ או במייל, עקבו אחרי הסטטוס וקבלו את ה-PDF החתום — אוטומטית.

כתובת בסיס https://sign.easy2sign.co.il/api/v1JSON · Bearer e2s_live_…
תוכן העניינים

מתחילים

מבוא

ה-API מבוסס REST ומחזיר JSON בקידוד UTF-8. כל הכתובות מתחילות ב-https://sign.easy2sign.co.il/api/v1. תאריכים הם מחרוזות ISO 8601 ב-UTC, ומזהים הם מחרוזות אטומות (אל תניחו מבנה או אורך). שדות חדשים עשויים להתווסף לתשובות בלי הודעה מוקדמת — קוד הלקוח צריך להתעלם משדות שאינו מכיר.

תהליך טיפוסי:

  1. בונים תבנית פעם אחת באפליקציה (קובץ, שדות, תפקידי חותמים ומשתנים) ומוצאים את המזהה שלה ב-GET /templates.
  2. לכל עסקה יוצרים מסמך מהתבנית עם פרטי החותמים והערכים, ושולחים אותו מיד (send: true).
  3. מקבלים Webhook כשהמסמך נחתם, ומורידים את ה-PDF החתום.

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

כל בקשה נושאת מפתח API בכותרת Authorization: Bearer e2s_live_… (גם x-api-key: e2s_live_… נתמך, לכלים כמו Zapier, Make ו-n8n). מנהל החשבון יוצר מפתחות בעמוד מפתחים באפליקציה. המפתח מוצג פעם אחת בלבד ונשמר אצלנו רק כגיבוב (SHA-256).

  • מפתח שייך לחשבון (workspace) אחד ופועל בשמו: הוא רואה את כל המסמכים והתבניות של החשבון.
  • שמרו את המפתח בצד השרת בלבד — לעולם לא בדפדפן, באפליקציית מובייל או במאגר קוד.
  • מפתח שדלף? בטלו אותו בעמוד המפתחים וצרו חדש. מפתח מבוטל, או חשבון מושעה, מקבלים 401.
  • גישת API היא חלק מהחבילה. בלעדיה כל בקשה מקבלת 403 plan_feature.
Request
curl "https://sign.easy2sign.co.il/api/v1/templates?limit=5" \
  -H "Authorization: Bearer $E2S_API_KEY"

Idempotency — ניסיון חוזר בטוח

בקשות POST שיוצרות או שולחות מקבלות כותרת Idempotency-Key (עד 200 תווים, למשל UUID או מזהה ההזמנה אצלכם). אם החיבור נפל באמצע, שלחו שוב את אותה בקשה עם אותו מפתח: הפעולה לא תתבצע פעמיים, והתשובה תחזיר את המצב הנוכחי של המשאב עם הכותרת Idempotent-Replayed: true.

  • נתמך ב: POST /documents, /documents/{id}/send, /remind, /void, POST /fill, וחובה ב-/fill/{id}/confirm.
  • המפתח שייך לחשבון ולפעולה. שימוש חוזר באותו מפתח עם גוף בקשה אחר מחזיר 422 idempotency_mismatch.
  • בקשה זהה שעדיין בעיבוד מחזירה 409 idempotency_in_progress — נסו שוב בעוד רגע.
  • רק תשובות מוצלחות נשמרות: אחרי שגיאה (למשל מכסה או חותם בלי נייד) אפשר לתקן ולנסות שוב עם אותו מפתח.
  • ביצירה, שליחה וביטול המפתח נשמר ביומן הביקורת של המסמך ולכן תקף לצמיתות; בתזכורת ובמסמך מטקסט — 24 שעות.

הגבלת קצב

עד 120 בקשות לדקה לכל מפתח. כל תשובה כוללת X-RateLimit-Limit, X-RateLimit-Remaining ו-X-Request-Id (צרפו אותו לפניות לתמיכה). חריגה מחזירה 429 rate_limited עם Retry-After בשניות.

  • תזכורות: עד 3 בשעה לכל חותם.
  • מסמך מטקסט: עד 60 קריאות למודל ב-10 דקות לכל חשבון, ועד 12 הודעות בבקשה אחת.

שגיאות

שגיאה מוחזרת תמיד באותו מבנה: code קבוע למכונה, message בעברית (מתאים להצגה למשתמש), messageEn באנגלית, ופרטים נוספים לפי המקרה (param, problem, metric…).

Response 400
{
  "error": {
    "code": "send_blocked",
    "message": "לחותם \"העובד\" חסר מספר נייד — אליו נשלחים הקישור וקוד האימות",
    "messageEn": "A signer cannot be reached (needs a valid mobile, or an email when email delivery is enabled)",
    "problem": "no_phone",
    "role": "העובד"
  }
}
codeHTTPמשמעות
validation_error400נתונים לא תקינים
unauthorized401מפתח API חסר או לא תקין
plan_limit402הגעתם למכסה של החבילה
ai_premium_required402הפעולה היא חלק מ-AI פרימיום
plan_feature403היכולת אינה כלולה בחבילה של החשבון
not_found404המשאב לא נמצא
invalid_state409הפעולה אינה אפשרית במצב הנוכחי של המסמך
idempotency_in_progress409בקשה עם אותו Idempotency-Key עדיין בעיבוד
idempotency_mismatch422המפתח Idempotency-Key כבר שימש לבקשה אחרת
rate_limited429יותר מדי בקשות, נא לנסות שוב בעוד רגע
internal_error500שגיאה פנימית, נסו שוב
ai_unavailable503מנוע ה-AI אינו זמין כרגע
send_blocked400המסמך לא יכול לצאת. problem: no_name, no_phone, bad_phone, field_unassigned, sender_field_empty
unknown_role · unknown_variable · invalid_value · invalid_phone · invalid_email · missing_signers · missing_values400שגיאות בגוף הבקשה ביצירת מסמך (ראו יצירת מסמך)
already_sent · not_on_turn · not_ready409המסמך כבר נשלח · עוד לא תורו של החותם · ה-PDF החתום עוד לא מוכן

חבילות ומכסות

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

  • מסמכים בחודש — נספרים בשליחה הראשונה (טיוטות לא נספרות). חריגה: 402 plan_limit עם metric: "documentsPerMonth", limit ו-used.
  • וואטסאפ — כשהמכסה החודשית נגמרת ההזמנות יוצאות במייל; חותם עם נייד בלבד מחזיר 402 (metric: "whatsappPerMonth").
  • מסמך מטקסט (AI פרימיום) — צורך ⚡ אנרגיה של AI פרימיום, בדיוק כמו באפליקציה. חשבון בלי AI פרימיום מקבל 402 ai_premium_required עם upgradeUrl למרכז ה-AI. כשהאנרגיה נגמרה מתקבל 402 plan_limit עם metric: "aiCreditsPerMonth" (שם השדה נשאר כפי שהוא) — פעולות חדשות ימתינו עד טעינת חבילת אנרגיה או החידוש ב-1 לחודש; פעולה שכבר התחילה מסתיימת.

מחזור החיים של מסמך

DRAFT→SENT→VIEWED→PARTIALLY_SIGNED→COMPLETED·VOIDED
סטטוסמשמעות
DRAFTנוצר ועדיין לא נשלח. אפשר לשלוח (/send) או לערוך באפליקציה.
SENTנשלח; החותמים שתורם הגיע הוזמנו.
VIEWEDלפחות חותם אחד פתח את הקישור.
PARTIALLY_SIGNEDחלק מהחותמים חתמו. בחתימה לפי סדר (SERIAL) הבא בתור מוזמן אוטומטית.
COMPLETEDכולם חתמו. ה-PDF נחתם דיגיטלית (PKI) עם תעודת השלמה. סופי.
VOIDEDבוטל: על ידיכם (/void), בסירוב של חותם, או כשעבר המועד האחרון. סופי.

סטטוס חותם: PENDING → VIEWED → SIGNED, או DECLINED. לכל חותם מוחזרים viewedAt, signedAt ו-declinedAt.

תבניות

רשימת תבניות

GET/api/v1/templates

התבניות של החשבון, מהחדשה לישנה, עם תפקידי החותמים (signers[].role) והמשתנים שהשולח ממלא (variables[].key) — אלה בדיוק הערכים שמעבירים ביצירת מסמך. ready: false ו-warnings מסמנים תבנית שמסמך ממנה לא יוכל לצאת כפי שהיא (למשל שדה של השולח שלא קושר למשתנה).

פרמטרים

שםסוגתיאור
limitinteger1–100, ברירת מחדל 25
cursorstringהערך של nextCursor מהעמוד הקודם

סוגי משתנים (type): person_name, id_number, company_id, phone, email, date, money, number, choice (אחד מתוך options), address, free_text.

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/templates" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "template",
      "id": "cm2tpl7w0000a1b2c3d4e5f6g",
      "title": "הסכם עבודה שעתי",
      "description": "הסכם העסקה לעובד שעתי",
      "version": 3,
      "signingMode": "SERIAL",
      "signers": [
        {
          "role": "העובד",
          "order": 1
        }
      ],
      "variables": [
        {
          "key": "employee_name",
          "label": "שם העובד",
          "type": "person_name",
          "required": true,
          "options": [],
          "default": null,
          "unit": null
        },
        {
          "key": "hourly_wage",
          "label": "שכר לשעה",
          "type": "money",
          "required": true,
          "options": [],
          "default": null,
          "unit": "₪ לשעה"
        },
        {
          "key": "start_date",
          "label": "תאריך תחילת עבודה",
          "type": "date",
          "required": true,
          "options": [],
          "default": null,
          "unit": null
        },
        {
          "key": "position",
          "label": "תפקיד",
          "type": "choice",
          "required": false,
          "options": [
            "מלצר",
            "טבח",
            "אחמ״ש"
          ],
          "default": "מלצר",
          "unit": null
        }
      ],
      "fieldCount": 9,
      "ready": true,
      "warnings": [],
      "createdAt": "2026-09-01T08:12:44.120Z",
      "updatedAt": "2026-10-02T11:03:10.551Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}

תבנית אחת

GET/api/v1/templates/{id}

כמו פריט ברשימה, ובנוסף fields: מפת השדות — מי ממלא כל שדה (signer, sender, profile, sender_signature), לאיזה תפקיד הוא שייך ולאיזה משתנה הוא מקושר.

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/templates/cm2tpl7w0000a1b2c3d4e5f6g" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "template",
  "id": "cm2tpl7w0000a1b2c3d4e5f6g",
  "title": "הסכם עבודה שעתי",
  "description": "הסכם העסקה לעובד שעתי",
  "version": 3,
  "signingMode": "SERIAL",
  "signers": [
    {
      "role": "העובד",
      "order": 1
    }
  ],
  "variables": [
    {
      "key": "employee_name",
      "label": "שם העובד",
      "type": "person_name",
      "required": true,
      "options": [],
      "default": null,
      "unit": null
    },
    {
      "key": "hourly_wage",
      "label": "שכר לשעה",
      "type": "money",
      "required": true,
      "options": [],
      "default": null,
      "unit": "₪ לשעה"
    },
    {
      "key": "start_date",
      "label": "תאריך תחילת עבודה",
      "type": "date",
      "required": true,
      "options": [],
      "default": null,
      "unit": null
    },
    {
      "key": "position",
      "label": "תפקיד",
      "type": "choice",
      "required": false,
      "options": [
        "מלצר",
        "טבח",
        "אחמ״ש"
      ],
      "default": "מלצר",
      "unit": null
    }
  ],
  "fieldCount": 9,
  "ready": true,
  "warnings": [],
  "createdAt": "2026-09-01T08:12:44.120Z",
  "updatedAt": "2026-10-02T11:03:10.551Z",
  "fields": [
    {
      "id": "cm2fld…01",
      "label": "שכר לשעה",
      "type": "TEXT",
      "page": 1,
      "required": true,
      "filledBy": "sender",
      "role": null,
      "variableKey": "hourly_wage"
    },
    {
      "id": "cm2fld…03",
      "label": "חתימת העובד",
      "type": "SIGNATURE",
      "page": 2,
      "required": true,
      "filledBy": "signer",
      "role": "העובד",
      "variableKey": null
    }
  ]
}

מסמכים

יצירת מסמך מתבנית

POST/api/v1/documentsIdempotency-Key

משכפל את התבנית (קובץ, שדות, תפקידים), ממלא את ערכי השולח בשדות המקושרים, שם את פרטי החותמים בתפקידים, ואם send: true — שולח מיד. שליחה שנדחתה (חותם בלי נייד, מכסה…) מבטלת את כל הפעולה: לא נשארת טיוטה חצי מוכנה, ואפשר לתקן ולנסות שוב עם אותו Idempotency-Key.

גוף הבקשה

שםסוגתיאור
templateIdחובהstringמזהה התבנית
titlestringכותרת המסמך. ברירת מחדל: שם התבנית
signersarray{ role, name, phone?, email? } לכל תפקיד בתבנית. role הוא שם התפקיד (לא תלוי רישיות); אפשר להשמיט כשיש תפקיד אחד. כשוואטסאפ פעיל חותם צריך נייד תקין (או מייל, כשמשלוח מייל פעיל). ב-send: true חובה לכל התפקידים.
valuesobject{ variableKey: value }. הערכים עוברים נרמול לפי סוג המשתנה (תאריך 2026-11-01 או 1.11.2026, סכום, ת״ז עם ספרת ביקורת, בחירה מתוך options…). משתנה חובה בלי ערך ובלי ברירת מחדל חוסם את send: true.
sendbooleanלשלוח מיד. ברירת מחדל false (טיוטה)
expiresAtstring (ISO 8601)מועד אחרון לחתימה. אחריו המסמך מבוטל אוטומטית
signingMode"SERIAL" | "PARALLEL"לפי סדר או במקביל. ברירת מחדל: כמו בתבנית

התשובה (201) היא המסמך המלא. אחרי שליחה כל חותם כולל signingUrl — קישור חתימה אישי שאפשר לשלוח גם בערוץ שלכם. התייחסו אליו כסוד: מי שמחזיק בו יכול לפתוח את המסמך (החתימה עצמה דורשת קוד אימות). warnings מפרט מה חסר בטיוטה.

דוגמה

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/documents" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "templateId": "cm2tpl7w0000a1b2c3d4e5f6g",
  "title": "הסכם עבודה – יוסי לוי",
  "signers": [
    {
      "role": "העובד",
      "name": "יוסי לוי",
      "phone": "050-1234567",
      "email": "yossi@example.com"
    }
  ],
  "values": {
    "employee_name": "יוסי לוי",
    "hourly_wage": 50,
    "start_date": "2026-11-01"
  },
  "send": true,
  "expiresAt": "2026-11-15T21:59:00Z"
}'
Response 201
{
  "object": "document",
  "id": "cm2doc4k20003h7j9m1n2p3q4",
  "title": "הסכם עבודה – יוסי לוי",
  "status": "SENT",
  "signingMode": "SERIAL",
  "createdVia": "API",
  "expiresAt": "2026-11-15T21:59:00.000Z",
  "completedAt": null,
  "createdAt": "2026-10-18T09:30:00.000Z",
  "updatedAt": "2026-10-18T09:30:02.000Z",
  "signers": [
    {
      "id": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "name": "יוסי לוי",
      "email": "yossi@example.com",
      "phone": "050-123-4567",
      "order": 1,
      "status": "PENDING",
      "viewedAt": null,
      "signedAt": null,
      "declinedAt": null,
      "signingUrl": "https://sign.easy2sign.co.il/sign/9QwX…"
    }
  ],
  "templateId": "cm2tpl7w0000a1b2c3d4e5f6g",
  "templateVersion": 3,
  "sentAt": "2026-10-18T09:30:02.000Z",
  "voidedAt": null,
  "voidReason": null,
  "values": {
    "employee_name": "יוסי לוי",
    "hourly_wage": "50",
    "start_date": "2026-11-01",
    "position": "מלצר"
  },
  "signedPdf": {
    "available": false,
    "sha256": null,
    "sealedAt": null
  },
  "warnings": []
}

רשימת מסמכים

GET/api/v1/documents

מסמכי החשבון (בלי תבניות ובלי מסמכים בסל), מהחדש לישן, בעמודים.

פרמטרים

שםסוגתיאור
statusstringסינון: DRAFT, SENT, VIEWED, PARTIALLY_SIGNED, COMPLETED, VOIDED
limitinteger1–100, ברירת מחדל 25
cursorstringהערך של nextCursor; כש-hasMore הוא false הגעתם לסוף

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/documents?status=COMPLETED&limit=50" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "document",
      "id": "cm2doc4k20003h7j9m1n2p3q4",
      "title": "הסכם עבודה – יוסי לוי",
      "status": "COMPLETED",
      "signingMode": "SERIAL",
      "createdVia": "API",
      "expiresAt": null,
      "completedAt": "2026-10-18T12:41:11.000Z",
      "createdAt": "2026-10-18T09:30:00.000Z",
      "updatedAt": "2026-10-18T12:41:11.000Z",
      "signers": [
        {
          "id": "cm2sgn8r50005x6y7z8a9b0c1",
          "role": "העובד",
          "name": "יוסי לוי",
          "email": "yossi@example.com",
          "phone": "050-123-4567",
          "order": 1,
          "status": "SIGNED",
          "viewedAt": null,
          "signedAt": "2026-10-18T12:41:08.000Z",
          "declinedAt": null
        }
      ]
    }
  ],
  "hasMore": true,
  "nextCursor": "cm2doc4k20003h7j9m1n2p3q4"
}

מסמך אחד

GET/api/v1/documents/{id}

הסטטוס, החותמים עם הסטטוס ושעות הצפייה/חתימה/סירוב של כל אחד, ערכי השולח (values), ומסמך שהושלם — גם fields: הערך הסופי של כל שדה (שדות חתימה מסומנים [signed]; את החתימות עצמן מורידים ב-PDF החתום).

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/documents/cm2doc4k20003h7j9m1n2p3q4" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "document",
  "id": "cm2doc4k20003h7j9m1n2p3q4",
  "title": "הסכם עבודה – יוסי לוי",
  "status": "COMPLETED",
  "signingMode": "SERIAL",
  "createdVia": "API",
  "expiresAt": "2026-11-15T21:59:00.000Z",
  "completedAt": "2026-10-18T12:41:09.000Z",
  "createdAt": "2026-10-18T09:30:00.000Z",
  "updatedAt": "2026-10-18T09:30:02.000Z",
  "signers": [
    {
      "id": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "name": "יוסי לוי",
      "email": "yossi@example.com",
      "phone": "050-123-4567",
      "order": 1,
      "status": "SIGNED",
      "viewedAt": "2026-10-18T10:02:51.000Z",
      "signedAt": "2026-10-18T12:41:08.000Z",
      "declinedAt": null
    }
  ],
  "templateId": "cm2tpl7w0000a1b2c3d4e5f6g",
  "templateVersion": 3,
  "sentAt": "2026-10-18T09:30:02.000Z",
  "voidedAt": null,
  "voidReason": null,
  "values": {
    "employee_name": "יוסי לוי",
    "hourly_wage": "50",
    "start_date": "2026-11-01",
    "position": "מלצר"
  },
  "signedPdf": {
    "available": true,
    "sha256": "4f9c1e…b72a",
    "sealedAt": "2026-10-18T12:41:11.000Z"
  },
  "fields": [
    {
      "id": "cm2fld…01",
      "label": "שכר לשעה",
      "type": "TEXT",
      "page": 1,
      "signerId": null,
      "role": null,
      "variableKey": "hourly_wage",
      "value": "50 ₪ לשעה"
    },
    {
      "id": "cm2fld…02",
      "label": "מספר תעודת זהות",
      "type": "TEXT",
      "page": 2,
      "signerId": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "variableKey": null,
      "value": "123456782"
    },
    {
      "id": "cm2fld…03",
      "label": "חתימת העובד",
      "type": "SIGNATURE",
      "page": 2,
      "signerId": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "variableKey": null,
      "value": "[signed]"
    }
  ]
}

שליחה לחתימה

POST/api/v1/documents/{id}/sendIdempotency-Key

שולח טיוטה לחותמים — אותו מסלול בדיוק של כפתור השליחה באפליקציה (בדיקות, מכסות, וואטסאפ/מייל, יומן ביקורת). נספר במכסת המסמכים החודשית. מסמך שכבר נשלח מחזיר 409 already_sent; לתזכורת השתמשו ב-/remind. בתשובה לכל חותם delivery: whatsapp, email, failed, none, או queued (בחתימה לפי סדר — יוזמן כשיגיע תורו).

דוגמה

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/documents/cm2doc4k20003h7j9m1n2p3q4/send" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Response 200
{
  "object": "document",
  "id": "cm2doc4k20003h7j9m1n2p3q4",
  "title": "הסכם עבודה – יוסי לוי",
  "status": "SENT",
  "signingMode": "SERIAL",
  "createdVia": "API",
  "expiresAt": "2026-11-15T21:59:00.000Z",
  "completedAt": null,
  "createdAt": "2026-10-18T09:30:00.000Z",
  "updatedAt": "2026-10-18T09:30:02.000Z",
  "signers": [
    {
      "id": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "name": "יוסי לוי",
      "email": "yossi@example.com",
      "phone": "050-123-4567",
      "order": 1,
      "status": "PENDING",
      "viewedAt": null,
      "signedAt": null,
      "declinedAt": null,
      "signingUrl": "https://sign.easy2sign.co.il/sign/9QwX…",
      "delivery": "whatsapp"
    }
  ],
  "templateId": "cm2tpl7w0000a1b2c3d4e5f6g",
  "templateVersion": 3,
  "sentAt": "2026-10-18T09:30:02.000Z",
  "voidedAt": null,
  "voidReason": null,
  "values": {
    "employee_name": "יוסי לוי",
    "hourly_wage": "50",
    "start_date": "2026-11-01",
    "position": "מלצר"
  },
  "signedPdf": {
    "available": false,
    "sha256": null,
    "sealedAt": null
  }
}

תזכורת

POST/api/v1/documents/{id}/remindIdempotency-Key

שולח שוב את הקישור לחותמים שתורם הגיע ועוד לא חתמו (או לחותם אחד, עם signerId). מי שעוד לא פתח מקבל שוב את נוסח ההזמנה, ומי שפתח — נוסח תזכורת. עד 3 תזכורות בשעה לכל חותם; חותם שחרג מסומן skipped.

גוף הבקשה

שםסוגתיאור
signerIdstringרק לחותם הזה (חייב להיות בתורו)

דוגמה

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/documents/cm2doc4k20003h7j9m1n2p3q4/remind" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Response 200
{
  "object": "reminder",
  "documentId": "cm2doc4k20003h7j9m1n2p3q4",
  "results": [
    {
      "signerId": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "delivery": "whatsapp"
    }
  ]
}

ביטול

POST/api/v1/documents/{id}/voidIdempotency-Key

מבטל מסמך שנשלח (או טיוטה). הקישורים מפסיקים לעבוד, תזכורות מתוזמנות מבוטלות והסיבה נרשמת ביומן הביקורת. ביטול הוא סופי, ואי אפשר לבטל מסמך שהושלם. נשלח Webhook document.voided עם reason: "api".

גוף הבקשה

שםסוגתיאור
reasonstringסיבה (עד 500 תווים), לתיעוד

דוגמה

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/documents/cm2doc4k20003h7j9m1n2p3q4/void" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "reason": "העסקה בוטלה"
}'
Response 200
{
  "object": "document",
  "id": "cm2doc4k20003h7j9m1n2p3q4",
  "title": "הסכם עבודה – יוסי לוי",
  "status": "VOIDED",
  "signingMode": "SERIAL",
  "createdVia": "API",
  "expiresAt": "2026-11-15T21:59:00.000Z",
  "completedAt": null,
  "createdAt": "2026-10-18T09:30:00.000Z",
  "updatedAt": "2026-10-18T09:30:02.000Z",
  "signers": [
    {
      "id": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "name": "יוסי לוי",
      "email": "yossi@example.com",
      "phone": "050-123-4567",
      "order": 1,
      "status": "PENDING",
      "viewedAt": null,
      "signedAt": null,
      "declinedAt": null
    }
  ],
  "templateId": "cm2tpl7w0000a1b2c3d4e5f6g",
  "templateVersion": 3,
  "sentAt": "2026-10-18T09:30:02.000Z",
  "voidedAt": "2026-10-19T07:15:00.000Z",
  "voidReason": "העסקה בוטלה",
  "values": {
    "employee_name": "יוסי לוי",
    "hourly_wage": "50",
    "start_date": "2026-11-01",
    "position": "מלצר"
  },
  "signedPdf": {
    "available": false,
    "sha256": null,
    "sealedAt": null
  }
}

הורדת ה-PDF החתום

GET/api/v1/documents/{id}/signed

קישור הורדה זמני (5 דקות) ל-PDF החתום דיגיטלית, עם גיבוב SHA-256 לאימות. עם ?redirect=1 התשובה היא הפניה (307) ישירה לקובץ. מסמך שעוד לא הושלם מחזיר 409 not_ready.

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/documents/cm2doc4k20003h7j9m1n2p3q4/signed" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "signed_pdf",
  "documentId": "cm2doc4k20003h7j9m1n2p3q4",
  "url": "https://…supabase.co/storage/v1/object/sign/documents/…/signed.pdf?token=…",
  "expiresAt": "2026-10-18T12:50:00.000Z",
  "sha256": "4f9c1e…b72a",
  "sealedAt": "2026-10-18T12:41:11.000Z"
}

יומן ביקורת

GET/api/v1/documents/{id}/audit

כל האירועים של המסמך, מהישן לחדש: יצירה, שליחה, פתיחה, אימות קוד, חתימה, סירוב, השלמה, ביטול והודעות וואטסאפ — עם IP, דפדפן ושעה. היומן שרשרת גיבובים: integrity מראה אם השרשרת שלמה.

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/documents/cm2doc4k20003h7j9m1n2p3q4/audit" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "audit_trail",
  "documentId": "cm2doc4k20003h7j9m1n2p3q4",
  "integrity": {
    "valid": true,
    "total": 6,
    "brokenAt": null
  },
  "events": [
    {
      "id": "cm2aud…01",
      "action": "CREATED",
      "at": "2026-10-18T09:30:00.000Z",
      "signerId": null,
      "role": null,
      "ip": "203.0.113.7",
      "userAgent": "node",
      "metadata": {
        "via": "template",
        "channel": "api",
        "templateId": "cm2tpl7w0000a1b2c3d4e5f6g"
      },
      "hash": "a1c3…"
    },
    {
      "id": "cm2aud…02",
      "action": "SENT",
      "at": "2026-10-18T09:30:02.000Z",
      "signerId": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "ip": "203.0.113.7",
      "userAgent": "node",
      "metadata": {
        "roleName": "העובד",
        "channel": "api"
      },
      "hash": "9be0…"
    },
    {
      "id": "cm2aud…05",
      "action": "SIGNED",
      "at": "2026-10-18T12:41:08.000Z",
      "signerId": "cm2sgn8r50005x6y7z8a9b0c1",
      "role": "העובד",
      "ip": "198.51.100.23",
      "userAgent": "Mozilla/5.0 …",
      "metadata": {},
      "hash": "77d2…"
    }
  ]
}

מסמך מטקסט (AI)

פתיחת בקשה מטקסט חופשי

POST/api/v1/fillIdempotency-Key

כותבים במילים מה צריך — למשל ״הסכם עבודה ליוסי לוי, 50 ש״ח לשעה, מתחיל ב-1.11, נייד 050-1234567״ — וה-AI בוחר תבנית, מחלץ את הערכים (בלי להמציא) ומכין טיוטה. שום דבר לא נשלח לפני אישור. הבקשה פעילה 24 שעות. חלק מ-AI פרימיום וצורך ⚡ אנרגיה (ראו חבילות ומכסות).

גוף הבקשה

שםסוגתיאור
textחובהstringהבקשה בעברית (עד 4,000 תווים)
templateIdstringלדלג על בחירת התבנית

status בתשובה: READY — יש טיוטה (documentId) ותצוגה מקדימה של הערכים; NEEDS_INFO — חסר משהו, השאלה ב-replyText ובפירוט ב-missing; NEEDS_TEMPLATE — לא ברור איזו תבנית, האפשרויות ב-templateOptions. עונים ב-/messages.

דוגמה

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/fill" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "text": "הסכם עבודה ליוסי לוי, 50 ש״ח לשעה, מתחיל ב-1.11, נייד 050-1234567"
}'
Response 201
{
  "object": "fill_session",
  "id": "cm2fil3d90002q4w6e8r0t2y4",
  "status": "READY",
  "mode": "TEMPLATE",
  "template": {
    "id": "cm2tpl7w0000a1b2c3d4e5f6g",
    "title": "הסכם עבודה שעתי"
  },
  "templateOptions": [],
  "values": [
    {
      "key": "employee_name",
      "label": "שם העובד",
      "valueType": "person_name",
      "value": "יוסי לוי",
      "display": "יוסי לוי",
      "inferred": false,
      "required": true
    },
    {
      "key": "hourly_wage",
      "label": "שכר לשעה",
      "valueType": "money",
      "value": "50",
      "display": "50 ₪ לשעה",
      "inferred": false,
      "required": true
    },
    {
      "key": "start_date",
      "label": "תאריך תחילת עבודה",
      "valueType": "date",
      "value": "2026-11-01",
      "display": "01.11.2026",
      "inferred": true,
      "required": true
    }
  ],
  "missing": [],
  "signer": {
    "name": "יוסי לוי",
    "phone": "972501234567",
    "email": null
  },
  "documentId": "cm2doc4k20003h7j9m1n2p3q4",
  "replyText": "הכנתי את הסכם העבודה ליוסי לוי. לשלוח לחתימה?",
  "warnings": [
    "החותם נקבע לפי השם שבמסמך: יוסי לוי."
  ]
}

מצב הבקשה

GET/api/v1/fill/{id}

אותו מבנה כמו בתשובת הפתיחה. בקשה שעברו עליה 24 שעות מסומנת EXPIRED.

Request
curl "https://sign.easy2sign.co.il/api/v1/fill/cm2fil3d90002q4w6e8r0t2y4" \
  -H "Authorization: Bearer $E2S_API_KEY"

תשובה או תיקון

POST/api/v1/fill/{id}/messages

ההודעה הבאה בשיחה: תשובה לשאלה, בחירת תבנית (״2״ או השם שלה) או תיקון (״השכר 55״). טיוטה מוכנה מתעדכנת במקום. עד 12 הודעות בבקשה.

גוף הבקשה

שםסוגתיאור
textחובהstringעד 4,000 תווים
Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/fill/cm2fil3d90002q4w6e8r0t2y4/messages" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "text": "השכר 55 ש״ח לשעה"
}'

אישור ושליחה

POST/api/v1/fill/{id}/confirmIdempotency-Key חובה

שולח את הטיוטה המוכנה (READY) לחותם, באותו מסלול שליחה ובאותן מכסות. אותו מפתח שוב מחזיר את התוצאה השמורה — המסמך לעולם לא נשלח פעמיים. אחרי האישור עוקבים אחרי המסמך ב-/documents/{documentId}.

דוגמה

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/fill/cm2fil3d90002q4w6e8r0t2y4/confirm" \
  -H "Authorization: Bearer $E2S_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Response 200
{
  "object": "fill_confirmation",
  "documentId": "cm2doc4k20003h7j9m1n2p3q4",
  "whatsapp": true,
  "links": [
    {
      "signerId": "cm2sgn8r50005x6y7z8a9b0c1",
      "roleName": "העובד",
      "url": "https://sign.easy2sign.co.il/sign/9QwX…",
      "delivery": "whatsapp",
      "hasPhone": true,
      "signed": false
    }
  ],
  "session": {
    "object": "fill_session",
    "id": "cm2fil3d90002q4w6e8r0t2y4",
    "status": "SENT",
    "mode": "TEMPLATE",
    "template": {
      "id": "cm2tpl7w0000a1b2c3d4e5f6g",
      "title": "הסכם עבודה שעתי"
    },
    "templateOptions": [],
    "values": [
      {
        "key": "employee_name",
        "label": "שם העובד",
        "valueType": "person_name",
        "value": "יוסי לוי",
        "display": "יוסי לוי",
        "inferred": false,
        "required": true
      },
      {
        "key": "hourly_wage",
        "label": "שכר לשעה",
        "valueType": "money",
        "value": "50",
        "display": "50 ₪ לשעה",
        "inferred": false,
        "required": true
      },
      {
        "key": "start_date",
        "label": "תאריך תחילת עבודה",
        "valueType": "date",
        "value": "2026-11-01",
        "display": "01.11.2026",
        "inferred": true,
        "required": true
      }
    ],
    "missing": [],
    "signer": {
      "name": "יוסי לוי",
      "phone": "972501234567",
      "email": null
    },
    "documentId": "cm2doc4k20003h7j9m1n2p3q4",
    "replyText": "המסמך נשלח לחתימה.",
    "warnings": [
      "החותם נקבע לפי השם שבמסמך: יוסי לוי."
    ]
  }
}

ביטול בקשה

POST/api/v1/fill/{id}/cancel

סוגר את הבקשה בלי לשלוח. טיוטה שכבר נוצרה נשארת ברשימת המסמכים (אפשר לבטל אותה ב-/void).

Request
curl -X POST "https://sign.easy2sign.co.il/api/v1/fill/cm2fil3d90002q4w6e8r0t2y4/cancel" \
  -H "Authorization: Bearer $E2S_API_KEY"

Webhooks

אירועים ומבנה המשלוח

במקום לתשאל את ה-API, הגדירו כתובת Webhook בעמוד מפתחים (מנהל החשבון, בחבילה שכוללת Webhooks). על כל אירוע נשלחת בקשת POST עם JSON לכתובות שנרשמו לו (רשימת אירועים ריקה = כל האירועים).

אירועמתיdata
document.signedחותם אחד סיים לחתום (נשלח לכל חותם)documentId, signerId
document.completedכל החותמים חתמו; ה-PDF החתום נוצר מיד אחר כךdocumentId
document.declinedחותם סירב לחתום (המסמך מבוטל ונשלח גם document.voided)documentId, signerId
document.voidedהמסמך בוטל: סירוב, פקיעת מועד, ביטול ידני מהאפליקציה, או ביטול דרך ה-APIdocumentId, reason
POST https://your-app.example.com/webhooks/easy2sign
Content-Type: application/json
X-Easy2Sign-Event: document.completed
X-Easy2Sign-Signature: 5d41402abc4b2a76b9719d911017c592…
X-Easy2Sign-Delivery: 0b6f3c1e-8f0a-4c55-9a77-3c1d2e4f5a6b
X-Easy2Sign-Timestamp: 1792312871
  • המשלוח הוא ניסיון יחיד עם זמן קצוב של 5 שניות, בלי ניסיונות חוזרים ובלי מעקב אחרי הפניות (3xx). ענו 2xx מהר ובצעו עבודה כבדה ברקע.
  • ה-Webhook מודיע שמשהו קרה; את המצב המלא קראו ב-GET /documents/{id}. אם פספסתם משלוח — סנכרנו מדי פעם עם GET /documents?status=….
  • id (וגם X-Easy2Sign-Delivery) ייחודי לכל משלוח — השתמשו בו למניעת כפילויות.
  • יעד חייב להיות כתובת https ציבורית (לא IP פנימי).

אימות החתימה

כל משלוח חתום ב-HMAC-SHA256 על גוף הבקשה הגולמי עם הסוד של ה-Webhook (מוצג בעמוד המפתחים), בקידוד hex, בכותרת X-Easy2Sign-Signature. חשבו את החתימה בעצמכם, השוו בהשוואה בזמן קבוע, ודחו משלוחים ישנים (לפי X-Easy2Sign-Timestamp או createdAt, שגם הוא חלק מהגוף החתום).

Verify
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.E2S_WEBHOOK_SECRET; // from /dashboard/developers
const seen = new Set(); // use your database in production

// The signature covers the RAW body: read it before any JSON parsing.
app.post("/webhooks/easy2sign", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.get("X-Easy2Sign-Signature") ?? "";
  const timestamp = Number(req.get("X-Easy2Sign-Timestamp"));

  const expected = crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
  const ok =
    signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex"));
  if (!ok) return res.status(401).end();

  // Replay defence: reject old deliveries and duplicates.
  if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > 300) return res.status(400).end();
  const event = JSON.parse(req.body.toString("utf8"));
  if (seen.has(event.id)) return res.status(200).end();
  seen.add(event.id);

  if (event.event === "document.completed") {
    // e.g. fetch the signed PDF: GET /api/v1/documents/{id}/signed
    console.log("completed", event.data.documentId);
  }
  res.status(200).end(); // answer fast (5s timeout); do slow work async
});

רשימת סוגי האירועים

GET/api/v1/webhooks/events

סוגי האירועים, שמות הכותרות ושיטת החתימה — בפורמט שמכונה יכולה לקרוא.

דוגמה

Request
curl "https://sign.easy2sign.co.il/api/v1/webhooks/events" \
  -H "Authorization: Bearer $E2S_API_KEY"
Response 200
{
  "object": "list",
  "data": [
    {
      "object": "webhook_event_type",
      "type": "document.completed",
      "description": "כל החותמים חתמו; ה-PDF החתום נוצר מיד אחר כך",
      "descriptionEn": "Every signer signed; the sealed PDF is produced right after",
      "data": {
        "documentId": "string"
      }
    }
  ],
  "headers": {
    "event": "X-Easy2Sign-Event",
    "signature": "X-Easy2Sign-Signature",
    "delivery": "X-Easy2Sign-Delivery",
    "timestamp": "X-Easy2Sign-Timestamp"
  },
  "signature": {
    "algorithm": "HMAC-SHA256",
    "encoding": "hex",
    "signedContent": "raw request body"
  }
}

מה עוד לא נתמך ב-v1

  • יצירת מסמך מקובץ PDF שמעלים — בינתיים רק מתבנית (בונים את התבנית פעם אחת באפליקציה).
  • הודעה אישית בהזמנה — ההזמנה נשלחת בנוסח הקבוע של המערכת.
  • ניהול תבניות, משתמשים וכתובות Webhook דרך ה-API — דרך האפליקציה בלבד.
  • ניסיונות חוזרים אוטומטיים למשלוחי Webhook.

צריכים משהו שחסר? כתבו לנו ל-support@easy2sign.co.il וצרפו את X-Request-Id של הבקשה.