Webhooks
Webhooks
Subscribe a target URL and Inkfree posts each matching signing event to it, signed so you can prove it came from us. Webhooks replace polling for envelope completion.
How it works
Subscribe with POST /api/v1/inkfree/webhooks. Inkfree then POSTs each matching event to your targetUrl. Target URLs must be HTTPS and publicly routable — loopback, link-local, and RFC 1918 private addresses are rejected.
One subscription listens for one event type. To receive several, create several subscriptions — they can share a target URL, and the X-Inkfree-Event header on each delivery tells you which fired.
Target URL requirements
HTTPS and publicly routable
Target URLs must be HTTPS. Loopback addresses, link-local addresses, and RFC 1918 private ranges are rejected with 400 — a subscription cannot point at localhost, 127.0.0.1, 169.254.x.x, or a10./172.16./192.168. address.
While developing, put a public tunnel or a request-bin style receiver in front of your local service.
Subscribing
The secret is the key Inkfree signs each delivery with. Send one of your own choosing and it is never read back to you by any endpoint — you already hold it. Omit it and one is generated for you, which is the single case where the API discloses a secret.
A generated secret is shown once — then never again
Omit secret and Inkfree generates one, returning it in the response as secret. That is the only time any endpoint discloses it. Read it out of that response and store it before you move on — if you lose it, it cannot be recovered, only replaced with PATCH /webhooks/{id}.
A secret you supply yourself is not echoed back, since you already hold it.
Subscriptions created before August 2026
secret stored nothing, and those deliveries went out unsigned — no X-Inkfree-Signature header at all. Existing subscriptions were not changed. If yours predates this and you want signed deliveries, set a secret on it with PATCH /webhooks/{id}.| Field | Type | Required | Description |
|---|---|---|---|
targetUrl | string (uri) | Required | HTTPS URL to POST events to. Must be publicly routable — loopback, link-local, and RFC 1918 private addresses are rejected. |
eventType | string | Required | Event to subscribe to. See GET /public/inkfree/webhooks/events for the authoritative list.envelope.sentenvelope.completedenvelope.voidedsigner.openedsigner.signedsigner.declinedsigner.delegated |
secret | string | Optional | Shared secret used to sign deliveries. Optional — omit it and Inkfree generates one, returning it in the response exactly once. A secret you supply here is never returned by any endpoint.write-only |
{
"targetUrl": "https://hooks.example.com/inkfree",
"eventType": "envelope.completed",
"secret": "whsec_your_shared_secret"
}curl -X POST "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"targetUrl": "https://hooks.example.com/inkfree",
"eventType": "envelope.completed",
"secret": "whsec_your_shared_secret"
}'{
"id": "whk_123",
"target_url": "https://hooks.example.com/inkfree",
"event_type": "envelope.completed",
"secret": "whsec_example_value_shown_once_at_creation",
"secret_note": "Store this now. It is shown only at creation and cannot be retrieved later; use PATCH /webhooks/{id} to rotate it if lost."
}The casing flips between request and response
The subscribe body is camelCase — targetUrl, eventType. The response, every webhook listing, and the PATCH /webhooks/{id} body are snake_case — target_url, event_type.
This is real behavior of the API, not a documentation slip. Follow the schema shown on each operation.
Managing subscriptions
Subscriptions can be listed, updated, paused, resumed, and removed. Pausing keeps the subscription but stops delivery; incoming events are dead-lettered while it is paused and can be recovered later.
- GET
/api/v1/inkfree/webhooksList webhook subscriptions - POST
/api/v1/inkfree/webhooksSubscribe to an event - PATCH
/api/v1/inkfree/webhooks/{id}Update target URL or rotate secret - DELETE
/api/v1/inkfree/webhooks/{id}Unsubscribe - POST
/api/v1/inkfree/webhooks/{id}/pausePause a subscription - POST
/api/v1/inkfree/webhooks/{id}/resumeResume a subscription
Next
Before pointing a production subscription at your receiver, verify the signature on every delivery — otherwise anything that learns the URL can post to it. See Verifying signatures.