ข้ามไปยังเนื้อหา

API คำขอลงนาม (Envelopes)

API envelopes ใช้ส่งเอกสารให้ลงนามจากระบบของคุณเอง envelope คือสิ่งที่แอปเรียกว่าคำขอลงนาม เป็นสิ่งเดียวกันภายใต้ชื่อที่ใช้ใน API คำขอลงนามหนึ่งรายการมีเอกสารได้สูงสุด 10 ฉบับ พร้อมผู้ที่ลงนามหรือรับเอกสาร และช่องที่ผู้ลงนามแต่ละคนต้องกรอก

AutomaDoc Sign บันทึกลายเซ็นอิเล็กทรอนิกส์แบบธรรมดาพร้อมบันทึกการตรวจสอบ ได้แก่ ใครลงนาม เมื่อใด จากที่ใด และลายนิ้วมือ (SHA-256) ของทุกไฟล์ ลายเซ็นนี้ไม่ใช่ลายเซ็นดิจิทัลที่ใช้ใบรับรอง เอกสารบางประเภท (พินัยกรรม เรื่องครอบครัว เอกสารยื่นต่อศาล) และระบบของหน่วยงานราชการบางแห่งต้องใช้ลายเซ็นรูปแบบอื่น โปรดตรวจสอบว่าเอกสารของคุณต้องใช้อะไร

ทุกเส้นทางต้องใช้คีย์ API ของบริษัท (ขึ้นต้นด้วย amk_) ในเฮดเดอร์ใดเฮดเดอร์หนึ่ง

X-Webhook-API-Key: amk_…
Authorization: Bearer amk_…

ผู้ดูแลสร้างคีย์ของบริษัทได้ในพอร์ทัลบริษัท ที่ บริษัท → คีย์ API (ดู เริ่มต้นใช้งาน API) คีย์ของเทมเพลตเปิดได้เฉพาะเทมเพลตนั้น ไม่ใช่คำขอลงนามของบริษัท จึงถูกปฏิเสธด้วย API_KEY_INVALID คีย์หนึ่งเห็นคำขอลงนามทุกรายการของบริษัท ไม่ว่าจะสร้างผ่าน API หรือในพอร์ทัล และไม่เห็นอะไรของบริษัทอื่นเลย (ENVELOPE_NOT_FOUND)

มีการจำกัดอัตราสองแบบ

  • 60 คำขอต่อนาทีต่อคีย์ รวมทุกเส้นทางของ envelope
  • 600 เอกสารต่อนาทีต่อบริษัท ใช้ร่วมกับ API เอกสาร และ HTTP trigger การสร้างหนึ่งครั้งนับหนึ่งต่อเอกสารที่อยู่ในนั้น

เมื่อเกินขีดจำกัดใดขีดจำกัดหนึ่ง คำตอบจะเป็น 429 พร้อม RATE_LIMITED

  1. POST /api/v1/envelopes จัดเก็บเอกสารของคุณและตอบ 201 ทันที โดยคำขอลงนามยังเป็น draft และเอกสารแต่ละฉบับเป็น prepareState: "pending"
  2. AutomaDoc จัดเตรียมเอกสารทุกฉบับ ไฟล์ Word, Excel และ PowerPoint จะกลายเป็น PDF และค้นหาจุดยึด (anchor) และแท็ก [[…]] ในข้อความ เอกสารที่ยังค้างอยู่หลัง 30 นาทีจะล้มเหลวด้วย timeout
  3. เมื่อเอกสารฉบับสุดท้ายพร้อม ระบบจะวางช่องจากจุดยึดและแท็ก และหากมี send: true คำขอลงนามจะถูกส่ง ผู้รับทางอีเมลที่ถึงคิวจะได้รับคำเชิญ
  4. อ่าน GET /api/v1/envelopes/:id เพื่อติดตาม หากส่งไม่ได้ คำขอจะยังเป็น draft และ sendError จะบอกเหตุผล

API สาธารณะไม่มีคำสั่งส่งแยกต่างหาก คำขอลงนามที่สร้างโดยไม่มี send: true จะยังเป็นฉบับร่าง ฉบับร่างที่ส่งไม่สำเร็จก็ลองใหม่ผ่าน API ไม่ได้ ให้สร้างคำขอลงนามใหม่ ฉบับร่างที่ไม่มีใครแก้ไขเป็นเวลา 30 วันจะถูกลบ

POST https://api.automadoc.cc/api/v1/envelopes

ส่งเนื้อหาเป็น JSON (Content-Type: application/json ไม่เกิน 14 MB) หรือเป็น multipart/form-data โดยมีส่วน envelope ที่บรรจุ JSON เดียวกัน และอีกหนึ่งส่วนต่อหนึ่งไฟล์ (ทั้งคำขอไม่เกิน 26 MB)

ฟิลด์ จำเป็น หน้าที่
title ใช่ แสดงให้ผู้ลงนามเห็นและในอีเมล ไม่เกิน 200 ตัวอักษร
message ไม่ ข้อความถึงผู้รับ ไม่เกิน 1,000 ตัวอักษร
documents ใช่ เอกสาร 1 ถึง 10 ฉบับ ตามลำดับ (ด้านล่าง)
recipients ใช่ ผู้รับ 1 ถึง 20 คน (ด้านล่าง)
fields ไม่ ช่องที่วางด้วยพิกัด (ด้านล่าง) ไม่เกิน 500
anchors ไม่ ช่องที่วางโดยอ้างอิงข้อความในเอกสาร (ด้านล่าง) ไม่เกิน 50
autoTags ไม่ true วางช่องจากแท็ก [[…]] ที่เขียนไว้ในเอกสาร (ด้านล่าง)
send ไม่ true ส่งคำขอลงนามทันทีที่จัดเตรียมเอกสารและวางช่องเสร็จ หากไม่ระบุจะยังเป็นฉบับร่าง
locale ไม่ ภาษาของอีเมลและหน้าลงนาม: en, zh, id, es, vi, th หรือ ja ค่าอื่นจะถูกละเว้น
timezone ไม่ เขตเวลา IANA (Asia/Jakarta) สำหรับวันที่ที่เขียนลงในเอกสารและใบรับรอง ค่าเริ่มต้น UTC
expiryDays ไม่ จำนวนวันนับจากส่งจนคำขอลงนามหมดอายุ: 1 ถึง 120 ค่าเริ่มต้น 30
reminders ไม่ { "everyDays": 3, "max": 3 } (ค่าเริ่มต้น โดย everyDays 1 ถึง 30 และ max 0 ถึง 10) หรือ false หากไม่ต้องการแจ้งเตือน
appendCertificate ไม่ ค่าเริ่มต้น true: PDF ที่ลงนามแล้วแต่ละไฟล์จะจบด้วยใบรับรองการเสร็จสิ้น ใบรับรองดาวน์โหลดแยกได้เสมอเช่นกัน

เอกสารแต่ละฉบับเป็นอย่างใดอย่างหนึ่งต่อไปนี้เท่านั้น

ฟิลด์ คืออะไร
base64 ไบต์ของไฟล์ในรูปแบบ base64 (รับคำนำหน้า data: ได้) เอกสาร base64 ทั้งหมดของคำขอรวมกันได้ไม่เกิน 10 MB หลังถอดรหัส ไฟล์ที่ใหญ่กว่านั้นให้ส่งแบบ multipart
file ชื่อของส่วนในคำขอ multipart ที่บรรจุไฟล์
generationId เอกสารที่ AutomaDoc สร้างให้บริษัทของคุณและเสร็จสมบูรณ์แล้ว (generationId ของ API เอกสาร หรือเอกสารที่สร้างอื่นใดที่ยังเก็บอยู่) ไฟล์จะถูกคัดลอกเข้ามาในคำขอลงนาม

name ไม่บังคับ ค่าเริ่มต้นคือชื่อไฟล์ของส่วนนั้น ชื่อของไฟล์ที่สร้าง หรือ “Document 1”, “Document 2” นามสกุล .pdf, .docx, .xlsx หรือ .pptx ที่ท้ายชื่อจะถูกตัดออก ไฟล์เป็น PDF, Word, Excel หรือ PowerPoint ได้ โดยระบุประเภทจากเนื้อหา ไม่ใช่จากชื่อ แต่ละไฟล์ไม่เกิน 25 MB และไฟล์ทั้งหมดของคำขอลงนามรวมกันไม่เกิน 50 MB

ฟิลด์ จำเป็น หน้าที่
key ใช่ ชื่อที่คุณตั้งเองสำหรับผู้รับนี้ (client) ใช้โดย fields และ anchors และส่งกลับมาในทุกคำตอบ ประกอบด้วยตัวอักษร ตัวเลข _, - หรือ . 1 ถึง 60 ตัว ไม่ซ้ำกันในคำขอ
role ใช่ signer (กรอกช่องและลงนาม) หรือ cc (รับผลลัพธ์ที่ลงนามแล้ว)
name ใช่ ไม่เกิน 120 ตัวอักษร
email เมื่อใช้ reach: "email" ที่อยู่ที่ส่งคำเชิญไป ไม่บังคับสำหรับผู้รับแบบลิงก์
reach ไม่ "email" (ค่าเริ่มต้น): AutomaDoc ส่งคำเชิญทางอีเมลเมื่อถึงคิวของผู้รับนี้ "link": ไม่มีการส่งอีเมล และคำตอบของการสร้างจะส่ง signingUrl กลับมาให้คุณนำไปส่งเอง
routingOrder ไม่ 1 ถึง 100 ค่าเริ่มต้น 1 ผู้รับที่มีหมายเลขเดียวกันลงนามพร้อมกันได้ หมายเลขที่สูงกว่าจะรอจนทุกคนที่มีหมายเลขต่ำกว่าลงนามเสร็จ
accessCode ไม่ รหัส 6 ถึง 128 ตัวอักษรที่ผู้รับต้องพิมพ์ก่อนเห็นเอกสาร ป้อนผิดห้าครั้งลิงก์จะถูกล็อก ส่งรหัสให้ผู้รับเอง และไม่ใช่ในข้อความเดียวกับลิงก์
slot ไม่ ใช้กับ autoTags: ชื่อบทบาทในแท็ก (Client) ที่ผู้รับนี้รับผิดชอบ
ฟิลด์ จำเป็น หน้าที่
document ใช่ ดัชนีของเอกสารใน documents เริ่มจาก 0
recipient ใช่ key ของผู้รับ เฉพาะผู้ลงนามที่มีช่อง
type ใช่ signature, initials, name, date_signed, text, checkbox, company หรือ email
page ใช่ หน้า เริ่มจาก 1
x, y, w, h ใช่ ตำแหน่งและขนาดเป็นพอยต์ (1/72 นิ้ว) วัดจากมุมซ้ายบนของหน้าตามที่แสดง (หลังการหมุนใด ๆ) ช่องต้องกว้างและสูงอย่างน้อย 8 พอยต์และอยู่ภายในหน้า
required ไม่ ค่าเริ่มต้น true
label ไม่ คำแนะนำที่แสดงให้ผู้ลงนามเห็น ไม่เกิน 100 ตัวอักษร
options ไม่ สำหรับช่องข้อความ: maxLength (1 ถึง 1,000), validate ("number" หรือ "email"), fontSize (6 ถึง 72 ย่อให้พอดีกับกรอบ)

name และ email เริ่มต้นด้วยชื่อและที่อยู่อีเมลของผู้รับ ซึ่งผู้ลงนามแก้ไขได้ ส่วน date_signed จะเติมด้วยวันที่ลงนาม ตามเขตเวลาของคำขอลงนาม หน้าและตำแหน่งจะถูกตรวจสอบกับเอกสารที่จัดเตรียมแล้วตอนส่งคำขอลงนาม (field_bad_page, field_off_page) เพราะไฟล์ Word ยังไม่มีหน้าจนกว่าจะถูกแปลง

จุดยึดวางช่องโดยอ้างอิงตำแหน่งจากข้อความที่มีอยู่ในเอกสารแล้ว คุณจึงไม่ต้องใช้พิกัด

ฟิลด์ จำเป็น หน้าที่
anchor ใช่ ข้อความที่จะค้นหา ไม่เกิน 200 ตัวอักษร การจับคู่ต้องตรงทุกตัวและแยกตัวพิมพ์ใหญ่เล็ก ช่องว่างหรือการขึ้นบรรทัดใหม่ที่ต่อกันกี่ตัวก็ตรงกับช่องว่างต่อเนื่องแบบอื่นได้
recipient ใช่ key ของผู้รับ
type ใช่ ประเภทช่อง ตามข้างต้น
occurrence ไม่ "all" (ค่าเริ่มต้น: หนึ่งช่องต่อทุกรายการที่ตรงกัน ไม่เกิน 200) หรือ n สำหรับรายการที่ตรงกันลำดับที่ n เท่านั้น นับรวมทุกเอกสารของคำขอลงนามตามลำดับการอ่าน
offsetX, offsetY ไม่ ระยะเป็นพอยต์จากมุมซ้ายบนของข้อความที่ตรงกันไปยังมุมซ้ายบนของช่อง (-2,000 ถึง 2,000 ค่าเริ่มต้น 0) offsetY ที่เป็นลบจะเลื่อนขึ้น
w, h ไม่ ขนาดของช่องเป็นพอยต์ (8 ถึง 1,000) ค่าเริ่มต้น: ลายเซ็น 160×48 อักษรย่อ 64×40 ช่องทำเครื่องหมาย 14×14 วันที่ 110×20 อีเมล 180×20 ข้อความอื่น ๆ 160×20
required, label ไม่ เหมือนกับช่องแบบพิกัด

ช่องที่จะล้นออกนอกหน้าจะถูกย้ายกลับเข้ามาในหน้า จุดยึดที่ไม่ตรงกับข้อความใดจะไม่สร้างช่อง ซึ่งมักปรากฏเป็น signer_without_fields ใน sendError

เมื่อใช้ autoTags: true แท็กที่เขียนในเอกสารจะกลายเป็นช่องของผู้รับที่ slot ตรงกับบทบาทของแท็ก (ตรงทุกตัว รวมถึงตัวพิมพ์ใหญ่เล็ก)

[[sign:Client]] [[initials:Client]] [[name:Client]] [[date:Client]]
[[text:Client:PO number]] [[check:Client]] [[company:Client]] [[email:Client]]
[[sign:Client;w=180;h=50]] [[text:Client:Notes;optional]]

มุมซ้ายบนของช่องคือมุมซ้ายบนของแท็ก ช่องจึงปิดทับแท็ก แท็กที่ไม่มีผู้รับคนใดรับบทบาทนั้นจะไม่สร้างช่อง

201 Created พร้อมคำขอลงนาม ทันทีหลังการสร้าง คำขอยังเป็นฉบับร่างที่เอกสารกำลังถูกจัดเตรียม

{
"id": "env_01JAB3K9Q7M2X8R4T6V0W1Y2Z3",
"status": "draft",
"finishing": false,
"finalizeFailed": false,
"title": "Service agreement ACME-2026-114",
"createdAt": 1792290600000,
"sentAt": null,
"expiresAt": null,
"completedAt": null,
"documents": [
{
"id": "doc_01JAB3K9RA5C7E9G1H3J5K7M9N",
"name": "Service agreement",
"prepareState": "pending",
"prepareError": null,
"pageCount": null,
"originalSha256": "3b7e0c…",
"preparedSha256": null,
"finalSha256": null,
"deliveredSha256": null
}
],
"recipients": [
{
"id": "rcp_01JAB3K9R2B4D6F8H0J2K4M6P8",
"key": "client",
"role": "signer",
"name": "Dana Lee",
"email": "dana@example.com",
"status": "created",
"routingOrder": 1,
"viewedAt": null,
"completedAt": null,
"declineReason": null
}
],
"auditHead": "a41f9d…",
"sendError": null
}

ผู้รับที่มี reach: "link" จะมี signingUrl (https://sign.automadoc.cc/#/…) ด้วย ในคำตอบนี้เท่านั้น การอ่านครั้งต่อ ๆ ไปจะไม่ส่งกลับมาอีก จึงต้องเก็บไว้ทันที ลิงก์จะเริ่มใช้งานได้เมื่อคำขอลงนามถูกส่ง คำเชิญและการแจ้งเตือนทางอีเมลแต่ละครั้งมีลิงก์ใหม่ ผู้รับแบบลิงก์จึงไม่ได้รับการแจ้งเตือนทางอีเมล

GET https://api.automadoc.cc/api/v1/envelopes/{envelopeId}

ตอบในรูปแบบเดียวกับการสร้าง ตามสถานะปัจจุบัน ระหว่างที่เอกสารกำลังจัดเตรียม ให้เรียกทุกไม่กี่วินาที เมื่อคำขอลงนามถูกส่งออกไปแล้ว เรียกทุกไม่กี่นาทีก็เพียงพอ

status ความหมาย
draft ยังไม่ส่ง: เอกสารกำลังจัดเตรียม ไม่ได้ขอ send หรือ sendError บอกเหตุผลที่ส่งไม่ได้
sent ส่งออกไปให้ลงนามแล้ว
completed ทุกคนลงนามแล้วและไฟล์ที่ลงนามแล้วพร้อมใช้
declined ผู้ลงนามปฏิเสธ declineReason อยู่ที่ผู้รับคนนั้น
voided คุณยกเลิกคำขอ
expired เลย expiresAt ก่อนที่ทุกคนจะลงนาม

finishing: true (พร้อม status: "sent") หมายความว่าทุกคนลงนามแล้วและกำลังสร้าง PDF ที่ลงนามแล้ว finalizeFailed: true หมายความว่าสร้างไม่ได้แม้ลองใหม่ครบทุกครั้งแล้ว ลายเซ็นยังเก็บไว้และทีมงานของเราได้รับการแจ้งเตือนแล้ว

ผู้รับมีสถานะ created (ยังไม่ถึงคิว) sent viewed แล้วจึง completed หรือ declined ผู้รับ cc เป็น sent ตั้งแต่แรก

เอกสารแต่ละฉบับมี SHA-256 ของทุกขั้น ได้แก่ originalSha256 (ไฟล์ของคุณ) preparedSha256 (PDF ที่ทุกคนเห็นและลงนาม) finalSha256 (ประทับลายเซ็นแล้ว) และ deliveredSha256 (ไฟล์ที่คุณดาวน์โหลด คือประทับลายเซ็นแล้ว พร้อมใบรับรองเมื่อเลือกแนบไว้) auditHead คือแฮชของเหตุการณ์ล่าสุดในบันทึกการตรวจสอบของคำขอลงนาม ทุกคนตรวจสอบไฟล์ที่ส่งมอบได้ด้วย POST https://api.automadoc.cc/api/verify และ { "sha256": "…" } (เลขฐานสิบหกตัวพิมพ์เล็กของทั้งไฟล์) ซึ่งจะตอบว่าไฟล์ตรงกับคำขอลงนามที่เสร็จสมบูรณ์หรือไม่

GET https://api.automadoc.cc/api/v1/envelopes?status=completed&since=1792290600000&limit=50
พารามิเตอร์ หน้าที่
status draft, sent, completed, declined, voided หรือ expired
since เฉพาะคำขอลงนามที่อัปเดตตั้งแต่เวลานี้ (Unix ms)
limit 1 ถึง 100 ค่าเริ่มต้น 25
cursor nextCursor ของหน้าก่อนหน้า

คำตอบคือ { "envelopes": [ … ], "nextCursor": "…" } เรียงจากใหม่ไปเก่า nextCursor เป็น null ในหน้าสุดท้าย key เป็น null สำหรับผู้รับของคำขอลงนามที่สร้างในพอร์ทัล

GET https://api.automadoc.cc/api/v1/envelopes/{envelopeId}/documents/{documentId}/signed
GET https://api.automadoc.cc/api/v1/envelopes/{envelopeId}/certificate
GET https://api.automadoc.cc/api/v1/envelopes/{envelopeId}/combined

signed คือเอกสารที่ลงนามแล้วหนึ่งฉบับ certificate คือใบรับรองการเสร็จสิ้นแยกต่างหาก combined คือเอกสารที่ลงนามแล้วทุกฉบับใน PDF เดียว (มีใบรับรองอยู่ท้ายเมื่อเลือกแนบไว้) ซึ่งสร้างเฉพาะคำขอลงนามที่มีเอกสารตั้งแต่สองฉบับ เส้นทางเหล่านี้ใช้ได้เมื่อคำขอลงนามเป็น completed แล้ว ก่อนหน้านั้นจะตอบ 409 พร้อม DOCUMENT_NOT_FOUND

คำตอบคือลิงก์อายุสั้น ไม่ใช่ตัวไฟล์

{
"url": "https://api.automadoc.cc/api/esign-files/env_01JAB3K9Q7M2X8R4T6V0W1Y2Z3/final/doc_01JAB3K9RA5C7E9G1H3J5K7M9N.pdf?e=…&d=a&n=…&s=…",
"filename": "Service agreement.pdf",
"expiresAt": 1792306800000,
"sha256": "e5a01c…"
}

ดึง url ภายใน 15 นาที โดยไม่ต้องใช้คีย์ หากต้องการลิงก์ใหม่ให้ขออีกครั้ง sha256 คือลายนิ้วมือของไฟล์ (สำหรับ signed คือ deliveredSha256 ของเอกสาร) การดาวน์โหลดทุกครั้งจะถูกบันทึกในบันทึกการตรวจสอบ ไฟล์ที่ลงนามแล้วของคำขอลงนามที่เสร็จสมบูรณ์จะเก็บไว้จนกว่าจะมีคนลบ

POST https://api.automadoc.cc/api/v1/envelopes/{envelopeId}/void
{ "reason": "Replaced by version 2" }

หยุดคำขอลงนามที่ส่งไปแล้ว ลิงก์จะใช้ไม่ได้อีก และผู้รับที่เคยได้รับคำขอจะได้รับแจ้งทางอีเมล ต้องระบุ reason (ไม่เกิน 500 ตัวอักษร) คำตอบคือคำขอลงนามซึ่งตอนนี้เป็น voided ยกเลิกได้เฉพาะคำขอลงนามที่ส่งแล้วและยังเปิดอยู่

POST https://api.automadoc.cc/api/v1/envelopes/{envelopeId}/recipients/{recipientId}/remind

recipientId คือ id ของผู้รับ (rcp_…) ไม่ใช่ key ของคุณ ส่งอีเมลพร้อมลิงก์ใหม่ถึงผู้รับทันที และลิงก์ในอีเมลก่อนหน้าจะใช้ไม่ได้อีก ใช้ได้เฉพาะกับผู้รับทางอีเมลที่ถึงคิว ไม่เกินหนึ่งครั้งทุก 10 นาที คำตอบคือ { "remindedAt": 1792300000000, "channel": "email" } การแจ้งเตือนอัตโนมัติเป็นไปตามการตั้งค่า reminders ของคำขอลงนามโดยไม่ต้องเรียก API

สร้างคำขอลงนามที่มีผู้ลงนามหนึ่งคน วางลายเซ็นไว้ข้างข้อความ “Client signature:” และวันที่ไว้ข้าง “Date:” แล้วส่ง JSON อยู่ในส่วน envelope และ PDF อยู่ในส่วนชื่อ contract

Terminal window
cat > envelope.json <<'EOF'
{
"title": "Service agreement ACME-2026-114",
"message": "Please review and sign by Friday.",
"timezone": "Asia/Jakarta",
"documents": [{ "name": "Service agreement", "file": "contract" }],
"recipients": [
{ "key": "client", "role": "signer", "name": "Dana Lee", "email": "dana@example.com" }
],
"anchors": [
{ "anchor": "Client signature:", "recipient": "client", "type": "signature", "offsetX": 110, "offsetY": -10 },
{ "anchor": "Date:", "recipient": "client", "type": "date_signed", "offsetX": 40, "occurrence": 1 }
],
"send": true
}
EOF
curl -X POST 'https://api.automadoc.cc/api/v1/envelopes' \
-H "X-Webhook-API-Key: $AUTOMADOC_KEY" \
-F 'envelope=<envelope.json' \
-F 'contract=@contract.pdf;type=application/pdf'

ติดตามจนกว่า status จะเป็น sent (หรือมีการตั้ง sendError) แล้วติดตามต่อจนเป็น completed

Terminal window
curl -s 'https://api.automadoc.cc/api/v1/envelopes/ENVELOPE_ID' \
-H "X-Webhook-API-Key: $AUTOMADOC_KEY"

เมื่อเสร็จสมบูรณ์แล้ว ขอลิงก์ของเอกสารที่ลงนามแล้วและดาวน์โหลด

Terminal window
url=$(curl -s 'https://api.automadoc.cc/api/v1/envelopes/ENVELOPE_ID/documents/DOCUMENT_ID/signed' \
-H "X-Webhook-API-Key: $AUTOMADOC_KEY" | jq -r .url)
curl -s -o signed.pdf "$url"

การสร้างแบบเดียวกันด้วย JSON จะใส่ไฟล์ใน base64 แทน: "documents": [{ "name": "Service agreement", "base64": "JVBERi0xLjcK…" }]

Node.js 18 ขึ้นไป รันด้วย AUTOMADOC_KEY=amk_… node sign.mjs

import { readFile, writeFile } from 'node:fs/promises'
import { createHash } from 'node:crypto'
const API = 'https://api.automadoc.cc'
const KEY = process.env.AUTOMADOC_KEY
async function call(method, path, body) {
const res = await fetch(API + path, {
method,
headers: body ? { 'X-Webhook-API-Key': KEY, 'Content-Type': 'application/json' } : { 'X-Webhook-API-Key': KEY },
body: body ? JSON.stringify(body) : undefined,
})
const json = await res.json()
if (!res.ok) throw new Error(`${res.status} ${json.code}: ${json.error}`)
return json
}
const pdf = await readFile('contract.pdf')
let envelope = await call('POST', '/api/v1/envelopes', {
title: 'Service agreement ACME-2026-114',
documents: [{ name: 'Service agreement', base64: pdf.toString('base64') }],
recipients: [{ key: 'client', role: 'signer', name: 'Dana Lee', email: 'dana@example.com' }],
anchors: [{ anchor: 'Client signature:', recipient: 'client', type: 'signature', offsetX: 110, offsetY: -10 }],
send: true,
})
// The documents are prepared and the fields placed, then the envelope is sent.
while (envelope.status === 'draft' && !envelope.sendError) {
await new Promise((resolve) => setTimeout(resolve, 2000))
envelope = await call('GET', `/api/v1/envelopes/${envelope.id}`)
}
if (envelope.sendError) throw new Error(`Not sent: ${JSON.stringify(envelope.sendError)}`)
console.log(`${envelope.id} is ${envelope.status}`)
// Later (a scheduled job, say): download every signed document of a completed envelope.
export async function downloadSigned(envelopeId) {
const current = await call('GET', `/api/v1/envelopes/${envelopeId}`)
if (current.status !== 'completed') return false
for (const doc of current.documents) {
const link = await call('GET', `/api/v1/envelopes/${envelopeId}/documents/${doc.id}/signed`)
const bytes = Buffer.from(await (await fetch(link.url)).arrayBuffer())
if (createHash('sha256').update(bytes).digest('hex') !== link.sha256) throw new Error('Download damaged')
await writeFile(`${doc.id}.pdf`, bytes)
}
return true
}

ข้อผิดพลาดอยู่ในรูปแบบ JSON: { "code": "…", "error": "English text" } พร้อม path ที่ระบุส่วนของคำขอที่มีปัญหา (recipients[1].email) หากมี

HTTP code เมื่อใด
400 INVALID_REQUEST คำขอไม่ถูกต้อง ดู path และ error
401 API_KEY_MISSING ไม่มีคีย์ใน X-Webhook-API-Key หรือ Authorization
403 API_KEY_INVALID ไม่รู้จักคีย์หรือคีย์ถูกเพิกถอน หรือเป็นคีย์ของเทมเพลต
403 ESIGN_SEND_BLOCKED แจ้งเตือน: การส่งของบริษัทคุณถูกระงับชั่วคราวระหว่างตรวจสอบรายงานเกี่ยวกับอีเมลของบริษัท โปรดติดต่อฝ่ายสนับสนุน
404 ENVELOPE_NOT_FOUND ไม่มีคำขอลงนามนี้ในบริษัทของคุณ
404 RECIPIENT_NOT_FOUND แจ้งเตือน: ไม่มีผู้รับนี้ในคำขอลงนาม
404 DOCUMENT_NOT_FOUND ดาวน์โหลด: ไม่มีเอกสารนี้ หรือไม่มีไฟล์นี้ (ไฟล์ combined ของคำขอลงนามที่มีเอกสารฉบับเดียว)
404 GENERATION_NOT_FOUND generationId ที่ไม่ใช่เอกสารที่สร้างของบริษัทคุณ
409 GENERATION_NOT_COMPLETED เอกสารที่สร้างยังไม่เสร็จสมบูรณ์ หรือไม่ได้เก็บไว้แล้ว
409 DOCUMENT_NOT_FOUND ดาวน์โหลดก่อนคำขอลงนามเสร็จสมบูรณ์
409 ENVELOPE_NOT_DRAFT ยกเลิกหรือแจ้งเตือนคำขอลงนามที่ไม่เคยถูกส่ง
409 ENVELOPE_CLOSED ยกเลิกหรือแจ้งเตือนคำขอลงนามที่เสร็จสมบูรณ์ ถูกปฏิเสธ ถูกยกเลิก หรือหมดอายุแล้ว
409 ENVELOPE_FINISHING ยกเลิกหรือแจ้งเตือนหลังจากทุกคนลงนามแล้ว ระหว่างที่กำลังสร้างไฟล์ที่ลงนามแล้ว
409 NOT_ALLOWED แจ้งเตือนผู้รับที่ยังไม่ถึงคิว หรือผู้รับแบบลิงก์
410 ENVELOPE_CLOSED ดาวน์โหลดหลังจากไฟล์ของคำขอลงนามถูกลบแล้ว
413 FILE_TOO_LARGE ไฟล์ใหญ่กว่า 25 MB หรือคำขอ multipart ใหญ่กว่า 26 MB
413 ENVELOPE_TOO_LARGE เอกสาร base64 รวมกันเกิน 10 MB หรือไฟล์รวมกันเกิน 50 MB
413 INVALID_REQUEST เนื้อหา JSON ใหญ่กว่า 14 MB
415 UNSUPPORTED_FILE ไฟล์ที่ไม่ใช่ PDF, Word, Excel หรือ PowerPoint
429 RATE_LIMITED เกิน 60 คำขอต่อนาทีสำหรับคีย์ หรือ 600 เอกสารต่อนาทีสำหรับบริษัท
429 ESIGN_SEND_RATE_LIMITED แจ้งเตือน: ผู้รับนี้ได้รับการแจ้งเตือนไปเมื่อไม่ถึง 10 นาทีที่แล้ว
502 ESIGN_WORKER_UNAVAILABLE แจ้งเตือน: ส่งการแจ้งเตือนไม่สำเร็จ
503 ESIGN_WORKER_UNSUPPORTED ขณะนี้จัดเตรียมเอกสารเพื่อลงนามไม่ได้ โปรดลองใหม่ภายหลัง ไม่มีสิ่งใดถูกสร้างขึ้น

การสร้างที่ถูกปฏิเสธระหว่างจัดเก็บเอกสารจะลบฉบับร่างและไฟล์ของฉบับร่างนั้น จึงไม่มีสิ่งที่สร้างค้างไว้ครึ่งทาง

เมื่อใช้ send: true การส่งจะเกิดขึ้นหลังจากการสร้างตอบกลับแล้ว เหตุผลที่ส่งไม่ได้จึงอยู่ใน sendError ของคำขอลงนาม (ซึ่งยังเป็น draft) ไม่ใช่สถานะ HTTP

sendError.code ความหมาย
SEND_PROBLEMS คำขอลงนามยังไม่สมบูรณ์ problems แสดงเหตุผล (ด้านล่าง)
QUOTA_EXCEEDED โควตารายเดือนและแพ็กเอกสารทุกแพ็กถูกใช้หมดแล้ว (ดูค่าใช้จ่าย)
ESIGN_SEND_RATE_LIMITED แผนฟรี: บริษัทของคุณส่งคำขอลงนามไปแล้ว 3 รายการในชั่วโมงที่ผ่านมา ทุกแผน: ส่งเกิน 10 ครั้งในหนึ่งนาที
ESIGN_RECIPIENT_CAP การส่งครั้งนี้จะเกินจำนวนผู้รับต่อวันที่บริษัทของคุณส่งถึงได้ (ด้านล่าง)
ESIGN_SEND_BLOCKED การส่งของบริษัทคุณถูกระงับชั่วคราวระหว่างตรวจสอบรายงานเกี่ยวกับอีเมลของบริษัท โปรดติดต่อฝ่ายสนับสนุน
ESIGN_EMAIL_UNAVAILABLE ส่งอีเมลสำหรับคำขอลงนามนี้ไม่ได้ ไม่มีการส่งหรือคิดค่าใช้จ่ายใด ๆ ผู้รับที่มี reach: "link" ยังใช้ได้
ESIGN_EMAIL_UNVERIFIED ผู้ที่สร้างคีย์ไม่มีที่อยู่อีเมลที่ยืนยันแล้ว
ESIGN_ALREADY_PENDING เอกสารที่สร้างนี้กำลังรอลงนามอยู่ในคำขอลงนามอื่น
INVALID_REQUEST แท็กและจุดยึดรวมกันสร้างช่องเกิน 500 ช่อง หรือเกิดข้อผิดพลาดที่ไม่คาดคิด

ปัญหาแต่ละรายการคือ { "code": "…" } พร้อม documentId, recipientId หรือ fieldId เมื่อเกี่ยวกับรายการใดรายการหนึ่ง (เป็น id ไม่ใช่ key ของคุณ)

ปัญหา ความหมาย
document_failed เอกสารจัดเตรียมไม่ได้ prepareError ของเอกสารบอกเหตุผล (ด้านล่าง)
too_many_pages เอกสารรวมกันเกิน 300 หน้า
envelope_too_large ไฟล์รวมกันเกิน 50 MB หรือ PDF ที่จัดเตรียมแล้วรวมกันเกิน 100 MB
no_signer ไม่มีผู้รับคนใดมีบทบาท signer
signer_without_fields ผู้ลงนามไม่มีช่อง: จุดยึดไม่ตรงกับข้อความใด หรือบทบาทของแท็กไม่มี slot
recipient_missing_email ผู้รับทางอีเมลไม่มีที่อยู่อีเมล
recipient_role_unavailable บทบาทอื่นที่ไม่ใช่ signer หรือ cc
too_many_fields เกิน 500 ช่อง
field_for_non_signer มีช่องที่มอบให้ผู้รับ cc
field_bad_page หน้าของช่องเกินหน้าสุดท้ายของเอกสาร
field_off_page ช่องล้นออกนอกหน้า หรือเล็กกว่า 8 พอยต์
field_type_unavailable ประเภทช่องอื่นที่ไม่ใช่แปดประเภทที่ระบุไว้ข้างต้น

prepareError ของเอกสารเป็นค่าใดค่าหนึ่งต่อไปนี้: pdf_encrypted (PDF ป้องกันด้วยรหัสผ่าน), file_too_large (PDF ที่จัดเตรียมแล้วจะเกิน 50 MB), too_many_pages, unsupported_file, invalid_file (ไฟล์เสียหาย), conversion_failed, source_unavailable, timeout หรือ internal

ขีดจำกัด ค่า
เอกสารต่อคำขอลงนาม 10
ไฟล์หนึ่งไฟล์ 25 MB
ไฟล์ทั้งหมดของคำขอลงนามหนึ่งรายการรวมกัน 50 MB
เอกสารที่จัดเตรียมแล้วหนึ่งฉบับ (PDF ที่ทุกคนลงนาม) 50 MB
เอกสารที่จัดเตรียมแล้วของคำขอลงนามหนึ่งรายการรวมกัน 100 MB
จำนวนหน้ารวมทุกเอกสารของคำขอลงนาม 300
ผู้รับต่อคำขอลงนาม 20
ช่องต่อคำขอลงนาม 500
จุดยึดต่อคำขอ 50 แต่ละจุดตรงกันได้ไม่เกิน 200 ครั้ง
เนื้อหาคำขอแบบ JSON 14 MB โดยมีเอกสาร base64 ไม่เกิน 10 MB
คำขอแบบ multipart 26 MB
วันหมดอายุ 1 ถึง 120 วันหลังส่ง ค่าเริ่มต้น 30
การแจ้งเตือน ทุก 1 ถึง 30 วัน ไม่เกิน 10 ครั้ง ค่าเริ่มต้นทุก 3 วัน 3 ครั้ง
รหัสเข้าถึงที่ผิดก่อนลิงก์ถูกล็อก 5
ลิงก์ดาวน์โหลด 15 นาที
ฉบับร่าง ลบหลังจากไม่มีการแก้ไข 30 วัน
ไฟล์ของคำขอลงนามที่ถูกปฏิเสธ ถูกยกเลิก และหมดอายุ ลบ 90 วันหลังปิด

หากต้องการส่งไฟล์เกิน 26 MB ให้เพิ่มด้วย generationId ซึ่งไม่ได้ส่งผ่านไปในคำขอ

เพดานการส่ง หากไม่มี Pro และไม่มีที่นั่ง Business บริษัทจะส่งคำขอลงนามได้ไม่เกิน 3 รายการต่อชั่วโมง และส่งถึงผู้รับได้ไม่เกิน 20 คนต่อวัน (5 คนต่อวันใน 24 ชั่วโมงแรกของบัญชี) หากมี Pro หรือที่นั่ง Business จะส่งถึงผู้รับได้สูงสุด 1,000 คนต่อวัน ผู้รับทุกคนนับรวม รวมถึง cc และผู้รับแบบลิงก์ ในช่วง 24 ชั่วโมงต่อเนื่อง ทุกบริษัทส่งคำขอลงนามได้ไม่เกิน 10 รายการต่อนาที

  • คำขอลงนามที่ส่งแล้วใช้เอกสารหนึ่งฉบับจากโควตาของคุณ ไม่ว่าจะมีเอกสารและผู้รับกี่คน คิดค่าใช้จ่ายเมื่อส่ง และไม่คืนให้หากภายหลังถูกยกเลิก ถูกปฏิเสธ หรือหมดอายุ ฉบับร่างไม่มีค่าใช้จ่าย
  • เอกสารที่ AutomaDoc สร้างส่งได้ฟรีในครั้งแรก คำขอลงนามที่เอกสารทุกฉบับมาจาก generationId ไม่มีค่าใช้จ่าย เว้นแต่มีฉบับใดเคยส่งในคำขอลงนามอื่นแล้ว ในกรณีนั้นจะนับเป็นเอกสารหนึ่งฉบับ คำขอลงนามที่มีทั้งไฟล์ที่สร้างและไฟล์ที่อัปโหลดนับเป็นหนึ่งฉบับ
  • สิ่งที่ชำระ คำขอลงนามที่ส่งด้วยคีย์ของบริษัทถือเป็นงานอัตโนมัติ เช่นเดียวกับ API เอกสาร ฟรีเมื่อมี Pro (หรือช่วงทดลองใช้) ในกรณีอื่นจะนับจากโควตาระบบอัตโนมัติของที่นั่ง Business ก่อน แล้วจึงเป็นโควตารายเดือนฟรี แล้วจึงเป็นแพ็กเอกสารของคุณ เมื่อใช้หมดทั้งหมด sendError จะเป็น QUOTA_EXCEEDED ที่นั่ง Starter เป็นของบุคคลและไม่ครอบคลุมการส่งผ่าน API

เพดานการส่งข้างต้นมีผลกับทุกแผน