API reference
Webhooks
Manage event subscriptions.
6 endpoints. Every path below is relative to the base URL.
On this page
https://api-uat.softsages.com/coreGET/api/v1/inkfree/webhooks
List webhook subscriptions
Requires the X-API-Key header
Returns every webhook subscription belonging to the tenant. The signing secret is never returned.
Responses
The tenant's subscriptions.
Returns WebhookSubscriptionSummary[]
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Optional | — |
target_url | string (uri) | Optional | Where events are delivered. |
event_type | string | Optional | Event this subscription listens for. |
status | string | Optional | Active or Paused — capitalized. Repeated delivery failures pause a subscription automatically.ActivePaused |
consecutive_failures | integer | Optional | Failed deliveries in a row. Reset to zero on resume. Returned by GET /webhooks only. |
last_success_at | string | Optional | When a delivery last succeeded. Returned by GET /webhooks only. This endpoint builds its rows by hand, so these two timestamps come out in ISO 8601 local form rather than the MM/dd/yyyy HH:mm:ss used on envelope objects. |
last_failure_at | string | Optional | When a delivery last failed, or null if none has. Returned by GET /webhooks only. |
[
{
"id": "whk_123",
"event_type": "envelope.completed",
"target_url": "https://hooks.example.com/inkfree",
"status": "Active",
"consecutive_failures": 0,
"last_success_at": "2026-01-15T10:30:00",
"last_failure_at": null
}
]The API key is missing, malformed, unknown, expired, revoked, or inactive.
Returns Error
{
"code": 401,
"message": "Invalid API key"
}Per-key rate limit exceeded. Back off and retry.
Returns Error
{
"code": 429,
"message": "Rate limit exceeded. Try again later."
}Example request
curl "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"POST/api/v1/inkfree/webhooks
Subscribe to an event
Requires the X-API-Key header
Registers a target URL to receive one event type.
The target must be HTTPS and publicly routable; loopback, link-local, and RFC 1918 private addresses are rejected with 400. An unrecognized eventType is likewise rejected — see GET /public/inkfree/webhooks/events for the valid set.
Supply a secret to sign deliveries with a value you already hold. If you omit it, Inkfree generates one and returns it in this response — once. That is the only time any endpoint discloses a secret, so store it immediately; a lost secret can only be replaced, via PATCH /webhooks/{id}. A secret you supplied yourself is never echoed back, because you already have it.
Note the casing: this request body is camelCase, while the response is snake_case.
Request bodyapplication/json · required
Schema: WebhookSubscriptionRequest
| 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"
}Responses
Subscription created. Carries the generated secret when the request omitted one.
Returns WebhookSubscriptionCreated
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Optional | — |
target_url | string (uri) | Optional | Where events will be delivered. |
event_type | string | Optional | Event this subscription listens for. |
secret | string | Optional | The generated signing secret, prefixed whsec_. Shown once, at creation, and never retrievable afterwards — store it before you discard the response. |
secret_note | string | Optional | Plain-language reminder that the secret is shown only once. |
{
"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."
}Target URL is not permitted, or the event type is unknown.
Returns Error
{
"code": 400,
"message": "target_url is not permitted"
}The API key is missing, malformed, unknown, expired, revoked, or inactive.
Returns Error
{
"code": 401,
"message": "Invalid API key"
}Per-key rate limit exceeded. Back off and retry.
Returns Error
{
"code": 429,
"message": "Rate limit exceeded. Try again later."
}Example request
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"
}'PATCH/api/v1/inkfree/webhooks/{id}
Update target URL or rotate secret
Requires the X-API-Key header
Changes the target URL, rotates the signing secret, or both. At least one of the two fields must be present, or the request is rejected with 400. A new target URL is validated exactly as on subscribe.
The response reports which fields changed rather than echoing the subscription.
Note the casing: unlike the subscribe body, this request uses snake_case.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Required | Webhook subscription id — a 36-character UUID.Example: whk_123 |
Request bodyapplication/json · required
Schema: WebhookUpdateRequest
| Field | Type | Required | Description |
|---|---|---|---|
target_url | string (uri) | Optional | New delivery URL. Validated exactly as on subscribe. |
secret | string | Optional | New signing secret, rotating the existing one.write-only |
{
"target_url": "https://hooks.example.com/inkfree/v2",
"secret": "whsec_rotated_value"
}Responses
Which fields changed.
Returns object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Optional | The subscription that was updated. |
target_url_changed | boolean | Optional | True when a new target_url was supplied. |
secret_rotated | boolean | Optional | True when a new secret was supplied. Note the field is secret_rotated, not secret_changed. |
{
"id": "whk_123",
"target_url_changed": true,
"secret_rotated": true
}Neither target_url nor secret supplied, or the target URL is not permitted.
Returns Error
{
"code": 400,
"message": "target_url or secret is required"
}The API key is missing, malformed, unknown, expired, revoked, or inactive.
Returns Error
{
"code": 401,
"message": "Invalid API key"
}The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.
Returns Error
{
"code": 404,
"message": "webhook subscription not found"
}Per-key rate limit exceeded. Back off and retry.
Returns Error
{
"code": 429,
"message": "Rate limit exceeded. Try again later."
}Example request
curl -X PATCH "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks/whk_123" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"target_url": "https://hooks.example.com/inkfree/v2",
"secret": "whsec_rotated_value"
}'DELETE/api/v1/inkfree/webhooks/{id}
Unsubscribe
Requires the X-API-Key header
Removes a subscription. No further events are delivered to its target URL.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Required | Webhook subscription id — a 36-character UUID.Example: whk_123 |
Responses
Subscription removed.
Returns ApiResponse
| Field | Type | Required | Description |
|---|---|---|---|
code | integer | Optional | HTTP status code, repeated in the body. |
message | string | Optional | Created object id, or a confirmation message. |
{
"code": 200,
"message": "Webhook subscription removed."
}The API key is missing, malformed, unknown, expired, revoked, or inactive.
Returns Error
{
"code": 401,
"message": "Invalid API key"
}The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.
Returns Error
{
"code": 404,
"message": "webhook subscription not found"
}Per-key rate limit exceeded. Back off and retry.
Returns Error
{
"code": 429,
"message": "Rate limit exceeded. Try again later."
}Example request
curl -X DELETE "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks/whk_123" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"POST/api/v1/inkfree/webhooks/{id}/pause
Pause a subscription
Requires the X-API-Key header
Stops delivery without deleting the subscription. While paused, incoming events for it are dead-lettered rather than delivered, and can be recovered later with the bulk replay endpoint.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Required | Webhook subscription id — a 36-character UUID.Example: whk_123 |
Responses
Subscription paused.
Returns ApiResponse
| Field | Type | Required | Description |
|---|---|---|---|
code | integer | Optional | HTTP status code, repeated in the body. |
message | string | Optional | Created object id, or a confirmation message. |
{
"code": 200,
"message": "Webhook subscription paused."
}The API key is missing, malformed, unknown, expired, revoked, or inactive.
Returns Error
{
"code": 401,
"message": "Invalid API key"
}The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.
Returns Error
{
"code": 404,
"message": "webhook subscription not found"
}Per-key rate limit exceeded. Back off and retry.
Returns Error
{
"code": 429,
"message": "Rate limit exceeded. Try again later."
}Example request
curl -X POST "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks/whk_123/pause" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"POST/api/v1/inkfree/webhooks/{id}/resume
Resume a subscription
Requires the X-API-Key header
Resumes delivery on a paused subscription and resets its consecutive-failure counter, clearing any automatic back-off.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Required | Webhook subscription id — a 36-character UUID.Example: whk_123 |
Responses
Subscription resumed.
Returns ApiResponse
| Field | Type | Required | Description |
|---|---|---|---|
code | integer | Optional | HTTP status code, repeated in the body. |
message | string | Optional | Created object id, or a confirmation message. |
{
"code": 200,
"message": "Webhook subscription resumed."
}The API key is missing, malformed, unknown, expired, revoked, or inactive.
Returns Error
{
"code": 401,
"message": "Invalid API key"
}The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.
Returns Error
{
"code": 404,
"message": "webhook subscription not found"
}Per-key rate limit exceeded. Back off and retry.
Returns Error
{
"code": 429,
"message": "Rate limit exceeded. Try again later."
}Example request
curl -X POST "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks/whk_123/resume" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"