Skip to main content

API reference

Webhooks

Manage event subscriptions.

6 endpoints. Every path below is relative to the base URL.

On this page
Base URL
https://api-uat.softsages.com/core

GET/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

200

The tenant's subscriptions.

Returns WebhookSubscriptionSummary[]

FieldTypeRequiredDescription
idstringOptional
target_urlstring (uri)OptionalWhere events are delivered.
event_typestringOptionalEvent this subscription listens for.
statusstringOptionalActive or Paused — capitalized. Repeated delivery failures pause a subscription automatically.ActivePaused
consecutive_failuresintegerOptionalFailed deliveries in a row. Reset to zero on resume. Returned by GET /webhooks only.
last_success_atstringOptionalWhen 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_atstringOptionalWhen a delivery last failed, or null if none has. Returned by GET /webhooks only.
200 response
[
  {
    "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
  }
]
401

The API key is missing, malformed, unknown, expired, revoked, or inactive.

Returns Error

401 response
{
  "code": 401,
  "message": "Invalid API key"
}
429

Per-key rate limit exceeded. Back off and retry.

Returns Error

429 response
{
  "code": 429,
  "message": "Rate limit exceeded. Try again later."
}

Example request

curl
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

FieldTypeRequiredDescription
targetUrlstring (uri)RequiredHTTPS URL to POST events to. Must be publicly routable — loopback, link-local, and RFC 1918 private addresses are rejected.
eventTypestringRequiredEvent to subscribe to. See GET /public/inkfree/webhooks/events for the authoritative list.envelope.sentenvelope.completedenvelope.voidedsigner.openedsigner.signedsigner.declinedsigner.delegated
secretstringOptionalShared 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
Example body
{
  "targetUrl": "https://hooks.example.com/inkfree",
  "eventType": "envelope.completed",
  "secret": "whsec_your_shared_secret"
}

Responses

200

Subscription created. Carries the generated secret when the request omitted one.

Returns WebhookSubscriptionCreated

FieldTypeRequiredDescription
idstringOptional
target_urlstring (uri)OptionalWhere events will be delivered.
event_typestringOptionalEvent this subscription listens for.
secretstringOptionalThe generated signing secret, prefixed whsec_. Shown once, at creation, and never retrievable afterwards — store it before you discard the response.
secret_notestringOptionalPlain-language reminder that the secret is shown only once.
200 response
{
  "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."
}
400

Target URL is not permitted, or the event type is unknown.

Returns Error

400 response
{
  "code": 400,
  "message": "target_url is not permitted"
}
401

The API key is missing, malformed, unknown, expired, revoked, or inactive.

Returns Error

401 response
{
  "code": 401,
  "message": "Invalid API key"
}
429

Per-key rate limit exceeded. Back off and retry.

Returns Error

429 response
{
  "code": 429,
  "message": "Rate limit exceeded. Try again later."
}

Example request

curl
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

NameInTypeRequiredDescription
idpathstringRequiredWebhook subscription id — a 36-character UUID.Example: whk_123

Request bodyapplication/json · required

Schema: WebhookUpdateRequest

FieldTypeRequiredDescription
target_urlstring (uri)OptionalNew delivery URL. Validated exactly as on subscribe.
secretstringOptionalNew signing secret, rotating the existing one.write-only
Example body
{
  "target_url": "https://hooks.example.com/inkfree/v2",
  "secret": "whsec_rotated_value"
}

Responses

200

Which fields changed.

Returns object

FieldTypeRequiredDescription
idstringOptionalThe subscription that was updated.
target_url_changedbooleanOptionalTrue when a new target_url was supplied.
secret_rotatedbooleanOptionalTrue when a new secret was supplied. Note the field is secret_rotated, not secret_changed.
200 response
{
  "id": "whk_123",
  "target_url_changed": true,
  "secret_rotated": true
}
400

Neither target_url nor secret supplied, or the target URL is not permitted.

Returns Error

400 response
{
  "code": 400,
  "message": "target_url or secret is required"
}
401

The API key is missing, malformed, unknown, expired, revoked, or inactive.

Returns Error

401 response
{
  "code": 401,
  "message": "Invalid API key"
}
404

The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.

Returns Error

404 response
{
  "code": 404,
  "message": "webhook subscription not found"
}
429

Per-key rate limit exceeded. Back off and retry.

Returns Error

429 response
{
  "code": 429,
  "message": "Rate limit exceeded. Try again later."
}

Example request

curl
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

NameInTypeRequiredDescription
idpathstringRequiredWebhook subscription id — a 36-character UUID.Example: whk_123

Responses

200

Subscription removed.

Returns ApiResponse

FieldTypeRequiredDescription
codeintegerOptionalHTTP status code, repeated in the body.
messagestringOptionalCreated object id, or a confirmation message.
200 response
{
  "code": 200,
  "message": "Webhook subscription removed."
}
401

The API key is missing, malformed, unknown, expired, revoked, or inactive.

Returns Error

401 response
{
  "code": 401,
  "message": "Invalid API key"
}
404

The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.

Returns Error

404 response
{
  "code": 404,
  "message": "webhook subscription not found"
}
429

Per-key rate limit exceeded. Back off and retry.

Returns Error

429 response
{
  "code": 429,
  "message": "Rate limit exceeded. Try again later."
}

Example request

curl
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

NameInTypeRequiredDescription
idpathstringRequiredWebhook subscription id — a 36-character UUID.Example: whk_123

Responses

200

Subscription paused.

Returns ApiResponse

FieldTypeRequiredDescription
codeintegerOptionalHTTP status code, repeated in the body.
messagestringOptionalCreated object id, or a confirmation message.
200 response
{
  "code": 200,
  "message": "Webhook subscription paused."
}
401

The API key is missing, malformed, unknown, expired, revoked, or inactive.

Returns Error

401 response
{
  "code": 401,
  "message": "Invalid API key"
}
404

The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.

Returns Error

404 response
{
  "code": 404,
  "message": "webhook subscription not found"
}
429

Per-key rate limit exceeded. Back off and retry.

Returns Error

429 response
{
  "code": 429,
  "message": "Rate limit exceeded. Try again later."
}

Example request

curl
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

NameInTypeRequiredDescription
idpathstringRequiredWebhook subscription id — a 36-character UUID.Example: whk_123

Responses

200

Subscription resumed.

Returns ApiResponse

FieldTypeRequiredDescription
codeintegerOptionalHTTP status code, repeated in the body.
messagestringOptionalCreated object id, or a confirmation message.
200 response
{
  "code": 200,
  "message": "Webhook subscription resumed."
}
401

The API key is missing, malformed, unknown, expired, revoked, or inactive.

Returns Error

401 response
{
  "code": 401,
  "message": "Invalid API key"
}
404

The subscription does not exist, or it belongs to another tenant. The two cases are deliberately indistinguishable.

Returns Error

404 response
{
  "code": 404,
  "message": "webhook subscription not found"
}
429

Per-key rate limit exceeded. Back off and retry.

Returns Error

429 response
{
  "code": 429,
  "message": "Rate limit exceeded. Try again later."
}

Example request

curl
curl -X POST "https://api-uat.softsages.com/core/api/v1/inkfree/webhooks/whk_123/resume" \
  -H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"