Ontwikkelaars · API · Webhooks

Eén POST. Verstuurd ter ondertekening.

Een REST API om pdf's ter ondertekening te versturen en elke ondertekenaar te volgen, ondertekende webhooks voor elke stap, idempotentiesleutels en stabiele foutcodes. API-sleutels en webhooks horen bij het Enterprise-plan.

Wat je kunt bouwen: handtekeningen vanuit je eigen software
curl https://api.wesign.now/v1/signing-requests \
  -H "Authorization: Bearer $WSK_KEY" \
  -H "Idempotency-Key: order-123/sign" \
  -F "file=@contract.pdf" \
  -F 'signers=[{"email":"jane@acme.com","role":"client"}]' \
  -F "placement=auto_append"

# → 201 Created
# {
#   "documentId": "8a1e4f9a-…",
#   "status": "pending",
#   "signers": [{
#     "role": "client",
#     "signingUrl": "https://acme.wesign.now/en/sign/…",
#     "emailed": true, …
#   }], …
# }
Wat je krijgt

Een API, webhooks en documentatie die ook je tools kunnen lezen.

REST API

Verstuur een pdf, volg elke ondertekenaar, stuur een herinnering of trek het verzoek in, en download de verzegelde pdf en de audittrail. Bearer-sleutels, JSON-antwoorden en een OpenAPI 3.1-specificatie met een id voor elke operatie.

API-overzicht

Ondertekende webhooks

signing_request.sent, .viewed, .signed, document.completed en meer, elk ondertekend met HMAC-SHA256. Een mislukte levering proberen we ongeveer 45 uur lang opnieuw; via het leveringslog kun je hem opnieuw versturen.

Webhook-events

Documentatie voor AI-assistenten

llms.txt somt elke documentatiepagina op, llms-full.txt bevat ze allemaal als platte tekst, openapi.json de exacte vorm van verzoeken en antwoorden. Geef ze aan je codeerassistent.

Voor AI-assistenten

Concrete voorbeelden.

Vier calls die de meeste integraties nodig hebben. Veldnamen zoals in de OpenAPI-specificatie.

1. Versturen met ankerplaatsing

Zet een marker zoals [[ls:signature:buyer]] in je pdf. Wij plaatsen daar het handtekeningveld van de koper en verbergen de marker. Geen marker in de pdf? Dan voegen we een handtekeningpagina toe.

POST /v1/signing-requests
Content-Type: multipart/form-data

file=@offer.pdf        # the PDF contains [[ls:signature:buyer]]
signers=[{"email":"buyer@acme.com","role":"buyer","name":"Ann Buyer"}]
placement=anchors

2. Meerdere ondertekenaars, op volgorde

Drie ondertekenaars, na elkaar. Ondertekenaar 2 wordt pas uitgenodigd als ondertekenaar 1 heeft getekend.

POST /v1/signing-requests
Content-Type: multipart/form-data

file=@contract.pdf
signing_mode=sequential
placement=auto_append
signers=[
  {"email":"founder@acme.com","role":"founder"},
  {"email":"investor@vc.example","role":"investor"},
  {"email":"witness@law.example","role":"witness"}
]

3. Webhook-ontvanger

Controleer de tijdstempel en de HMAC over de ruwe body en handel dan het event af.

// Node + Express. The full verifier (Node and PHP) is in the docs.
app.post('/wesign/callback', express.raw({ type: 'application/json' }), (req, res) => {
  // X-WeSign-Signature: t=<unix seconds>,v1=<hex>  (two v1 for 24 h after a rotation)
  const parts = (req.get('x-wesign-signature') ?? '').split(',')
  const t = parts[0]?.startsWith('t=') ? parts[0].slice(2) : ''
  if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.status(401).end()
  const expected = crypto.createHmac('sha256', SECRET)
    .update(`${t}.${req.body}`).digest()
  const valid = parts.filter((p) => p.startsWith('v1=')).some((p) => {
    const got = Buffer.from(p.slice(3), 'hex')
    return got.length === expected.length && crypto.timingSafeEqual(got, expected)
  })
  if (!valid) return res.status(401).end()

  const evt = JSON.parse(req.body.toString('utf8'))
  if (evt.event === 'document.completed') {
    // fetch evt.signed_pdf_url with your API key, compare evt.sha256, keep a copy
  }
  res.sendStatus(200)
})

4. Idempotente herhaling

Dezelfde sleutel met dezelfde body binnen 24 uur geeft het eerste antwoord opnieuw, dus een herhaling na een netwerkfout verstuurt nooit dubbel.

POST /v1/signing-requests
Idempotency-Key: order-123/sign

# First call:                      201 Created
# Same key + same body (24 h):     201, the same body, Idempotent-Replayed: true
# Same key while the first runs:   409 idempotency_in_progress + Retry-After
# Same key + a different body:     422 idempotency_key_reuse

Gebouwd voor productie.

Bearer-sleutels, twee scopes

Elke sleutel hoort bij één workspace. Een full-sleutel roept de hele API aan; een embedded-sleutel beheert alleen ingebedde ondertekensessies. Beperk een sleutel tot je IP-adressen; intrekken werkt meteen.

60 verzoeken per minuut per sleutel

Eén vast venster per sleutel over alle /v1-endpoints. Geslaagde antwoorden hebben RateLimit-*-headers; een 429 heeft Retry-After.

Stabiele foutcodes

Elke fout is JSON met een leesbare melding (error), een stabiele code en, waar het helpt, meta. Vergelijk op code; de melding kan veranderen.

Verzegelde, controleerbare pdf's

De ondertekende pdf draagt een PAdES-zegel dat elke conforme reader kan controleren. De audittrail toont elk event met tijdstip, het e-mailadres en het gemaskeerde IP-adres van de ondertekenaar en elke sms-codecontrole.

API-toegang hoort bij Enterprise.

API-sleutels en webhooks maken deel uit van het Enterprise-plan. Vertel ons wat je wilt koppelen. De documentatie is openbaar, dus je kunt hem eerst lezen.