E
Ejad PDF Signer v1.1.0
Checking...

توقيع مستند PDF

جرّب الخدمة بطريقتين: رفع مباشر (Multipart) أو JSON (Base64)

الملف يُرفع كـ multipart/form-data → يُوقّع → يُنزَّل كـ binary
أو ألصق نص base64 يدوياً في الأسفل ⬇
يقبل أيضاً data URL: data:application/pdf;base64,...
JSON: للـ APIs · Binary: للتنزيل المباشر

📋 نتيجة التوقيع

API Reference

استخدم الخدمة برمجياً من أي بيئة

Endpoint

POST https://signer.ejadtech.sa/sign

Request

multipart/form-data · حقل pdf (مطلوب) + reason, location, contact

Response

application/pdf (binary) · الملف الموقّع مباشرة

Code Examples

curl -X POST https://signer.ejadtech.sa/sign \
  -H "X-API-Key: $SIGNER_KEY" \
  -F "pdf=@document.pdf" \
  -F "reason=Approved" \
  -o signed.pdf
import requests

session = requests.Session()
session.headers.update({"X-API-Key": "..."})

with open("doc.pdf", "rb") as f:
    r = session.post(
        "https://signer.ejadtech.sa/sign",
        files={"pdf": f},
        data={"reason": "Approved"},
        timeout=30,
    )
r.raise_for_status()
open("signed.pdf", "wb").write(r.content)
import fs from "node:fs";

const form = new FormData();
form.append("pdf",
  new Blob([fs.readFileSync("doc.pdf")]),
  "doc.pdf");
form.append("reason", "Approved");

const res = await fetch("https://signer.ejadtech.sa/sign", {
  method: "POST",
  headers: { "X-API-Key": process.env.SIGNER_KEY },
  body: form,
});
fs.writeFileSync("signed.pdf",
  Buffer.from(await res.arrayBuffer()));

Endpoint

POST https://signer.ejadtech.sa/sign-base64

Request Body (JSON)

{
  "pdf_base64": "JVBERi0xLjQK...",
  "reason": "Approved",
  "location": "Riyadh, SA",
  "contact": "devops@ejadtech.sa",
  "return_format": "base64"  // or "binary"
}

Response (return_format=base64)

{
  "success": true,
  "pdf_base64": "JVBERi0xLjQK...",
  "original_size": 12345,
  "signed_size": 15678,
  "filename": "signed.pdf"
}

Code Examples

PDF_B64=$(base64 -w0 document.pdf)

curl -X POST https://signer.ejadtech.sa/sign-base64 \
  -H "X-API-Key: $SIGNER_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"pdf_base64\": \"$PDF_B64\",
    \"reason\": \"Approved\",
    \"return_format\": \"base64\"
  }" | jq -r '.pdf_base64' | base64 -d > signed.pdf
import base64, requests

with open("doc.pdf", "rb") as f:
    pdf_b64 = base64.b64encode(f.read()).decode()

r = requests.post(
    "https://signer.ejadtech.sa/sign-base64",
    headers={"X-API-Key": "..."},
    json={
        "pdf_base64": pdf_b64,
        "reason": "Approved",
        "return_format": "base64",
    },
    timeout=30,
)
r.raise_for_status()
data = r.json()
open("signed.pdf", "wb").write(base64.b64decode(data["pdf_base64"]))
import fs from "node:fs";

const pdfB64 = fs.readFileSync("doc.pdf").toString("base64");

const res = await fetch("https://signer.ejadtech.sa/sign-base64", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.SIGNER_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    pdf_base64: pdfB64,
    reason: "Approved",
    return_format: "base64",
  }),
});
const data = await res.json();
fs.writeFileSync("signed.pdf",
  Buffer.from(data.pdf_base64, "base64"));
# داخل Odoo model — التكامل السلس
import requests

class DocumentSigner(models.Model):
    _name = 'document.signer'

    def sign_attachment(self, attachment):
        # attachment.datas في Odoo يكون base64 أصلاً!
        key = self.env['ir.config_parameter'].sudo().get_param('signer.key')
        r = requests.post(
            'https://signer.ejadtech.sa/sign-base64',
            headers={'X-API-Key': key},
            json={
                'pdf_base64': attachment.datas.decode(),
                'reason': f'Signed by {self.env.user.name}',
                'return_format': 'base64',
            }, timeout=30,
        )
        r.raise_for_status()
        return self.env['ir.attachment'].create({
            'name': f'{attachment.name}_signed.pdf',
            'datas': r.json()['pdf_base64'],
            'mimetype': 'application/pdf',
        })

Performance Best Practices

  • 1
    Keep-Alive: Session() / AsyncClient يوفر ~200ms/طلب (TLS handshake).
  • 2
    Multipart vs Base64: Multipart أسرع لملفات كبيرة (>5MB). Base64 أفضل لـ JSON APIs و ERP integrations.
  • 3
    التوقيع المتوازي: asyncio.gather بحد 10-15 طلب متزامن.
  • 4
    Timeout: 30 ثانية — العملية cryptographic ولا تُقطع مبكراً.
  • 5
    حد الحجم: 50MB افتراضياً — للأكبر استخدم multipart وقسّم الملف.

Response Codes

  • 200 — الملف الموقّع (binary أو JSON)
  • 400 — PDF غير صالح / base64 خاطئ
  • 401 — API key غير صحيح
  • 413 — الملف أكبر من الحد المسموح
  • 500 — خطأ داخلي (راجع اللوق)