Ondertekenen vanuit je eigen software.
PDF’s online bewerken in je platform
De volledige online PDF-bewerker werkt zonder lokale installatie. Openen, tekst en formulieren bewerken, pagina’s beheren, stempels en handtekeningen plaatsen en PDF’s downloaden gebeuren in de browser.
Met /inki-platform.js kan je platform een PDF aanbieden in een apart bewerkervenster. Na een expliciete klik geeft de gebruiker de bewerkte PDF terug aan het platform. Je frontend heeft geen API-sleutel nodig; de gebruiker logt in bij inki-pdf. Hiervoor moeten de exacte HTTPS-platformdomeinen eerst worden toegestaan. Iframe-embedding en SSO zijn nog niet beschikbaar.
const verbinding = InkiPDF.open({
bytes: pdfArrayBuffer,
naam: 'opdracht.pdf',
onSave: ({bytes, naam}) => bewaarInEigenPlatform(bytes, naam),
onError: toonFout
});
verbinding.ready.catch(toonFout);Laad de SDK vanaf https://inki-pdf.nl/inki-platform.js en open het venster vanuit een gebruikersklik. De ontwikkelaarsdocumentatie in GitHub beschrijft domeintoestemming, bestandslimieten en beveiliging.
Alles wat de bewerker van inki-pdf doet, kan jouw software ook: een pdf ter ondertekening aanbieden, de status volgen en het getekende, gewaarmerkte document ophalen. Eén REST-API met JSON, zonder SDK of extra bibliotheken.
De API zit in Business Pro en Enterprise. Maak in Mijn account een tijdelijke API-sleutel met de benodigde lees- en schrijfrechten. Bewaar die uitsluitend op je platformserver en trek hem in zodra de koppeling vervalt. Basisadres: https://inki-pdf.nl, of je eigen server bij Enterprise.
In het kort
- Verzoek aanmakenStuur de pdf (base64), de ondertekenaars en de tekenvakken. Je krijgt per ondertekenaar een link terug; de server mailt die als een e-mailadres is opgegeven.
- Status volgenZet een webhook: dan meldt inki-pdf elke stap aan jouw server. Of vraag de status op wanneer je wilt.
- Document ophalenZodra iedereen heeft getekend: het gewaarmerkte document, het logboek en het voltooiingscertificaat.
Inloggen
Elke serveraanroep naar /api/onderteken/… gebruikt een API-sleutel:
Authorization: Bearer jouw_api_sleutel
Een fout geeft HTTP 403 met {"ok": false, "reden": "…"}. Alle antwoorden zijn JSON met ok, behalve de pdf-downloads.
Een verzoek aanmaken
POST/api/onderteken/verzoeken
| Veld | Betekenis |
|---|---|
naam | Bestandsnaam zoals de klant hem ziet, bijvoorbeeld offerte-2026-0412.pdf. |
bestand_b64 | De pdf, base64-gecodeerd. Hoogstens 60 MB. |
ondertekenaars | Lijst van {naam, email, telefoon, rol}. E-mail mag leeg: dan geef je de link zelf door. rol is ondertekenaar (standaard) of getuige. Een tot tien. |
vakken | Lijst van {soort, pagina, x, y, b, h, ondertekenaar, label}. Soorten: handtekening, naam, datum, paraaf, tekst (invulveld), vinkje. Pagina telt vanaf 0. Maten in pdf-punten (1/72 inch), gemeten vanaf de linkerbovenhoek van het blad; b en h zijn breedte en hoogte. ondertekenaar is de index in de lijst (0 = de eerste). |
bericht | Tekst in de uitnodiging en op de tekenpagina. |
afzender_naam, afzender_email | Wie het vraagt; het e-mailadres krijgt bericht bij elke handtekening, weigering of opmerking. |
code_nodig | true (standaard): de klant bevestigt met een eenmalige code per mail. false: zonder code. |
taal | De taal van de tekenpagina en de mails: nl (standaard), en, de, fr, es, it, pl, tr, ar. |
bewaren_dagen | 7, 14 (standaard) of 30: zoveel dagen na afronding wist de server het document. Het logboek met de vingerafdrukken blijft. |
volgorde | true: in volgorde tekenen; de volgende krijgt pas zijn link als de vorige heeft getekend. |
herinner_dagen | 0 (geen), 2, 3 of 7: elke zoveel dagen een herinnering aan wie nog niet tekende, hoogstens drie. |
verloopt_dagen | 0 (nooit), 7, 14 of 30: daarna sluit het verzoek vanzelf als niet iedereen heeft getekend. |
verzend_op | Datum en tijd (2026-11-01T09:00:00): dan pas verzenden. Leeg = nu. |
huisstijl | {naam, kleur, logo_b64}: je naam, kleur (#rrggbb) en logo (PNG, hoogstens 400 kB) op de tekenpagina. |
bulk_groep | Een eigen kenmerk om losse verzoeken (ieder zijn eigen exemplaar) bij elkaar te houden. Maak per ontvanger een verzoek. |
Het antwoord is de samenvatting van het verzoek, met per ondertekenaar de link (en de code, als er geen mail is ingesteld):
{"ok": true, "verzoek": {
"id": "3f9c0b2a1e7d4c88", "naam": "offerte-2026-0412.pdf", "status": "verzonden", "mail": true,
"ondertekenaars": [{"nr": 0, "naam": "Klant Jansen", "email": "jansen@voorbeeld.nl", "status": "verzonden",
"link": "https://inki-pdf.nl/teken/…", "aan_de_beurt": true, "rol": "ondertekenaar"}],
"volgorde": false, "verloopt_op": null, "bewaren_dagen": 14, "getekend": false, "zegel": null }}
Status en documenten
| Aanroep | Wat je krijgt |
|---|---|
| GET/api/onderteken/lijst | Al je verzoeken, nieuwste eerst, elk als samenvatting hierboven. |
| GET/api/onderteken/{id}/status | Eén verzoek. Statussen: gepland, verzonden, bekeken, getekend, geweigerd, ingetrokken, verlopen. |
| GET/api/onderteken/{id}/getekend.pdf | Het complete, gewaarmerkte document (409 zolang niet iedereen heeft getekend; 410 als het na de bewaartermijn is gewist). |
| GET/api/onderteken/{id}/document.pdf | De laatste versie, ook als nog niet iedereen heeft getekend. |
| GET/api/onderteken/{id}/certificaat | Het voltooiingscertificaat als JSON: versies met SHA-256, per ondertekenaar het logboek (tijd, gebeurtenis, IP, browser), opmerkingen, zegel. |
| GET/api/onderteken/{id}/zegel | Het cryptografische zegel nalopen: is het bestand onveranderd, zijn de handtekeningen intact. |
| POST/api/onderteken/{id}/herinner | Body {"nr": 0}: nu een herinnering mailen aan die ondertekenaar. |
| POST/api/onderteken/{id}/intrek | Het verzoek intrekken; de links werken niet meer. |
| POST/api/onderteken/{id}/opruimen | Het document nu van de server wissen (alleen een afgerond verzoek); het logboek blijft. |
| POST/api/controle | Openbaar, zonder inlog. Body {"sha256": "…"}: hoort deze vingerafdruk bij een getekend document, en wie tekende wanneer. Zonder het document te sturen. |
Webhooks: bericht bij elke stap
In plaats van de status te blijven opvragen laat je inki-pdf jouw server bellen zodra er iets gebeurt: een klant bekijkt het document, tekent, weigert, stelt een vraag, of het verzoek verloopt. Zo zet je een opdracht in je eigen systeem op "akkoord", haal je het getekende document automatisch in het dossier of maak je een taak aan als iemand niet tekent.
| Aanroep | Wat het doet |
|---|---|
| POST/api/onderteken/webhook | Body {"url": "https://jouwserver.nl/inki", "gebeurtenissen": ["getekend", "afgerond"]}. Laat gebeurtenissen weg voor alles. Het antwoord bevat eenmalig het geheim (whsec_…): bewaar het, je ziet het niet nog eens. Een tweede aanroep vervangt adres én geheim. |
| GET/api/onderteken/webhook | De instelling en de laatste honderd afleveringen: gebeurtenis, tijd, pogingen, HTTP-status, of het aankwam. |
| POST/api/onderteken/webhook/test | Stuurt een testbericht (gebeurtenis test) naar je adres. |
| POST/api/onderteken/webhook/verwijder | Zet de webhook uit; wat nog in de wachtrij stond vervalt. |
Gebeurtenissen: verzonden, bekeken, getekend (per ondertekenaar), afgerond (iedereen heeft getekend; het gewaarmerkte document staat klaar), geweigerd, ingetrokken, verlopen, herinnerd, opmerking en gewist (het document is na de bewaartermijn van de server gehaald).
Elk bericht is een POST met JSON. De kop X-Inki-Gebeurtenis zegt wat er gebeurde, X-Inki-Id is uniek per bericht (zodat je een herhaling herkent) en X-Inki-Handtekening is sha256= gevolgd door de HMAC-SHA256 van de ruwe inhoud met jouw geheim als sleutel. Controleer die handtekening voordat je iets doet; dan weet je dat het bericht van inki-pdf komt en onderweg niet is veranderd.
{"id": "evt_3a1f…", "gebeurtenis": "afgerond", "tijd": "2026-10-04T10:12:31",
"verzoek": {"id": "3f9c0b2a1e7d4c88", "naam": "offerte-2026-0412.pdf", "status": "getekend", "getekend": true,
"bulk_groep": null, "afgerond": "2026-10-04T10:12:31",
"ondertekenaars": [{"nr": 0, "naam": "Klant Jansen", "email": "jansen@voorbeeld.nl", "rol": "ondertekenaar", "status": "getekend"}]},
"document": {"getekend_pdf": "https://inki-pdf.nl/api/onderteken/3f9c0b2a1e7d4c88/getekend.pdf",
"certificaat": "https://inki-pdf.nl/api/onderteken/3f9c0b2a1e7d4c88/certificaat",
"sha256": "9f2c…", "gezegeld": true, "bewaren_dagen": 14}}
Bij getekend, bekeken, herinnerd, geweigerd en opmerking staat er ook een veld ondertekenaar ({nr, naam, email, rol, status}); bij opmerking de tekst, bij geweigerd de reden, bij gewist de reden. De links in document vragen je gewone API-koppen. Antwoord met een HTTP-status 200 tot 299 binnen tien seconden; doe het werk daarna. Lukt dat niet, dan proberen we het opnieuw na 1 en 5 minuten, een half uur, twee uur, zes uur en een dag; daarna staat het bericht als opgegeven in het overzicht. Een bericht kan dus vaker aankomen: kijk naar X-Inki-Id.
Controle van de handtekening in Python:
import hashlib, hmac
def klopt(geheim: str, inhoud: bytes, kop: str) -> bool:
verwacht = "sha256=" + hmac.new(geheim.encode(), inhoud, hashlib.sha256).hexdigest()
return hmac.compare_digest(verwacht, kop)
Voorbeeld in Python
import base64, json, urllib.request
BASIS = "https://inki-pdf.nl"
KOPPEN = {"X-Gebruiker": "api@jouwbedrijf.nl", "X-Wachtwoord": "…", "Content-Type": "application/json"}
def api(methode, pad, body=None):
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(f"{BASIS}{pad}", data=data, method=methode, headers=KOPPEN)
with urllib.request.urlopen(req) as r:
return json.loads(r.read())
pdf = base64.b64encode(open("offerte.pdf", "rb").read()).decode()
uit = api("POST", "/api/onderteken/verzoeken", {
"naam": "offerte-2026-0412.pdf", "bestand_b64": pdf,
"ondertekenaars": [{"naam": "Klant Jansen", "email": "jansen@voorbeeld.nl"}],
"vakken": [{"soort": "handtekening", "pagina": 0, "x": 60, "y": 640, "b": 180, "h": 50, "ondertekenaar": 0},
{"soort": "datum", "pagina": 0, "x": 300, "y": 640, "b": 120, "h": 30, "ondertekenaar": 0}],
"bericht": "Graag tekenen voor akkoord.", "afzender_naam": "Jouw Bedrijf", "afzender_email": "jij@jouwbedrijf.nl",
"herinner_dagen": 3, "verloopt_dagen": 14,
})
verzoek_id = uit["verzoek"]["id"]
# Later: is het getekend?
status = api("GET", f"/api/onderteken/{verzoek_id}/status")["verzoek"]
if status["getekend"]:
req = urllib.request.Request(f"{BASIS}/api/onderteken/{verzoek_id}/getekend.pdf", headers=KOPPEN)
open("offerte-getekend.pdf", "wb").write(urllib.request.urlopen(req).read())
Voorbeeld met curl
curl -s https://inki-pdf.nl/api/onderteken/lijst \
-H "X-Gebruiker: api@jouwbedrijf.nl" -H "X-Wachtwoord: …"
curl -s -o getekend.pdf https://inki-pdf.nl/api/onderteken/3f9c0b2a1e7d4c88/getekend.pdf \
-H "X-Gebruiker: api@jouwbedrijf.nl" -H "X-Wachtwoord: …"
Goed om te weten
- Bericht bij elke stapHet afzenderadres krijgt een mail bij elke handtekening, weigering, opmerking en bij het verlopen. Wil je het in je eigen systeem bijwerken, zet dan een webhook (hierboven); de status opvragen kan altijd.
- De tekenvakken bepaal je zelfWil je de posities uit de bewerker halen? Zet de vakken daar, bewaar ze als sjabloon en lees de coördinaten af. Of meet ze in je eigen pdf-generator: de oorsprong is linksboven, in punten.
- Limieten van je plan gelden ook hierAantal ondertekenaars, verzoeken per maand en de bewaartermijn volgen uit je abonnement. Een aanroep die er buiten valt geeft 400 met de reden.
- Op je eigen serverBij Enterprise draait dezelfde server bij jou; het basisadres is dan het jouwe en documenten verlaten je netwerk niet. Vraag een offerte.
Vragen over de koppeling? ondersteuning@inki-pdf.nl
