curl --request POST \
--url https://my.flowsign.app/api/v1/webhooks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://hooks.example.co.nz/flowsign",
"events": [
"PACKAGE_COMPLETED",
"PACKAGE_DECLINED"
],
"description": "Production CRM sync",
"enabled": true
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://hooks.example.co.nz/flowsign',
events: ['PACKAGE_COMPLETED', 'PACKAGE_DECLINED'],
description: 'Production CRM sync',
enabled: true
})
};
fetch('https://my.flowsign.app/api/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://hooks.example.co.nz/flowsign',
events: ['PACKAGE_COMPLETED', 'PACKAGE_DECLINED'],
description: 'Production CRM sync',
enabled: true
})
};
fetch('https://my.flowsign.app/api/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://my.flowsign.app/api/v1/webhooks';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://hooks.example.co.nz/flowsign',
events: ['PACKAGE_COMPLETED', 'PACKAGE_DECLINED'],
description: 'Production CRM sync',
enabled: true
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));import requests
url = "https://my.flowsign.app/api/v1/webhooks"
payload = {
"url": "https://hooks.example.co.nz/flowsign",
"events": ["PACKAGE_COMPLETED", "PACKAGE_DECLINED"],
"description": "Production CRM sync",
"enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)using RestSharp;
var options = new RestClientOptions("https://my.flowsign.app/api/v1/webhooks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"url\": \"https://hooks.example.co.nz/flowsign\",\n \"events\": [\n \"PACKAGE_COMPLETED\",\n \"PACKAGE_DECLINED\"\n ],\n \"description\": \"Production CRM sync\",\n \"enabled\": true\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
using RestSharp;
var options = new RestClientOptions("https://my.flowsign.app/api/v1/webhooks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"url\": \"https://hooks.example.co.nz/flowsign\",\n \"events\": [\n \"PACKAGE_COMPLETED\",\n \"PACKAGE_DECLINED\"\n ],\n \"description\": \"Production CRM sync\",\n \"enabled\": true\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
$headers=@{}
$headers.Add("Authorization", "Bearer <token>")
$headers.Add("Content-Type", "application/json")
$response = Invoke-WebRequest -Uri 'https://my.flowsign.app/api/v1/webhooks' -Method POST -Headers $headers -ContentType 'application/json' -Body '{
"url": "https://hooks.example.co.nz/flowsign",
"events": [
"PACKAGE_COMPLETED",
"PACKAGE_DECLINED"
],
"description": "Production CRM sync",
"enabled": true
}'{
"data": {
"id": "cmg1h7t2k0003v8p9d4q6xw2e",
"url": "https://hooks.example.co.nz/flowsign",
"secret": "whsec_4f7a1c9e2b8d6f3a5c0e7b9d1f4a6c8e2b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a",
"events": [
"PACKAGE_COMPLETED",
"PACKAGE_DECLINED"
],
"enabled": true,
"createdAt": "2026-09-14T02:15:30.000Z"
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}Register a webhook endpoint
Registers an HTTPS URL to receive the selected events from the caller’s workspace. Requires canManageWebhooks.
curl --request POST \
--url https://my.flowsign.app/api/v1/webhooks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://hooks.example.co.nz/flowsign",
"events": [
"PACKAGE_COMPLETED",
"PACKAGE_DECLINED"
],
"description": "Production CRM sync",
"enabled": true
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://hooks.example.co.nz/flowsign',
events: ['PACKAGE_COMPLETED', 'PACKAGE_DECLINED'],
description: 'Production CRM sync',
enabled: true
})
};
fetch('https://my.flowsign.app/api/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://hooks.example.co.nz/flowsign',
events: ['PACKAGE_COMPLETED', 'PACKAGE_DECLINED'],
description: 'Production CRM sync',
enabled: true
})
};
fetch('https://my.flowsign.app/api/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://my.flowsign.app/api/v1/webhooks';
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://hooks.example.co.nz/flowsign',
events: ['PACKAGE_COMPLETED', 'PACKAGE_DECLINED'],
description: 'Production CRM sync',
enabled: true
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));import requests
url = "https://my.flowsign.app/api/v1/webhooks"
payload = {
"url": "https://hooks.example.co.nz/flowsign",
"events": ["PACKAGE_COMPLETED", "PACKAGE_DECLINED"],
"description": "Production CRM sync",
"enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)using RestSharp;
var options = new RestClientOptions("https://my.flowsign.app/api/v1/webhooks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"url\": \"https://hooks.example.co.nz/flowsign\",\n \"events\": [\n \"PACKAGE_COMPLETED\",\n \"PACKAGE_DECLINED\"\n ],\n \"description\": \"Production CRM sync\",\n \"enabled\": true\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
using RestSharp;
var options = new RestClientOptions("https://my.flowsign.app/api/v1/webhooks");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"url\": \"https://hooks.example.co.nz/flowsign\",\n \"events\": [\n \"PACKAGE_COMPLETED\",\n \"PACKAGE_DECLINED\"\n ],\n \"description\": \"Production CRM sync\",\n \"enabled\": true\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
$headers=@{}
$headers.Add("Authorization", "Bearer <token>")
$headers.Add("Content-Type", "application/json")
$response = Invoke-WebRequest -Uri 'https://my.flowsign.app/api/v1/webhooks' -Method POST -Headers $headers -ContentType 'application/json' -Body '{
"url": "https://hooks.example.co.nz/flowsign",
"events": [
"PACKAGE_COMPLETED",
"PACKAGE_DECLINED"
],
"description": "Production CRM sync",
"enabled": true
}'{
"data": {
"id": "cmg1h7t2k0003v8p9d4q6xw2e",
"url": "https://hooks.example.co.nz/flowsign",
"secret": "whsec_4f7a1c9e2b8d6f3a5c0e7b9d1f4a6c8e2b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a",
"events": [
"PACKAGE_COMPLETED",
"PACKAGE_DECLINED"
],
"enabled": true,
"createdAt": "2026-09-14T02:15:30.000Z"
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}{
"error": "Missing permission: canSendPackages",
"details": {
"recipients.0.email": [
"Invalid email"
]
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
The workspace the key was issued for, as returned by GET /api/v1/workspaces. Optional: omitting it acts in the key's workspace, and any other id is rejected with 401.
Body
HTTPS URL to POST events to. Rejected when it is not HTTPS or its host is localhost, a .local/.internal name, or a private, loopback, link-local or multicast address. Redirects are not followed at delivery time.
"https://hooks.example.co.nz/flowsign"
Events to subscribe to. At least one.
1Event name. PACKAGE_SENT: a package was sent to its recipients. PACKAGE_COMPLETED: every recipient finished and the package is complete. PACKAGE_VOIDED: the sender voided the package. PACKAGE_EXPIRED: the package passed its expiry before completing. PACKAGE_DECLINED: a recipient declined and the package stopped. PACKAGE_ON_HOLD: the sender paused signing on the package. PACKAGE_RESUMED: a package on hold went back out for signing. PACKAGE_SCHEDULED: the package was scheduled to send later, or moved to a new time. PACKAGE_DELETED: a package that was scheduled or out for signing was deleted. SESSION_SENT: one recipient's signing invitation was sent. SESSION_OPENED: a recipient opened their signing link. SESSION_COMPLETED: a recipient finished their step. SESSION_DECLINED: a recipient declined their step. SESSION_REMINDED: a recipient was sent a reminder. SESSION_CANCELLED: a recipient's open signing session ended because the package was declined, voided, expired or deleted, or a correction removed them.
PACKAGE_SENT, PACKAGE_COMPLETED, PACKAGE_VOIDED, PACKAGE_EXPIRED, PACKAGE_DECLINED, PACKAGE_ON_HOLD, PACKAGE_RESUMED, PACKAGE_SCHEDULED, PACKAGE_DELETED, SESSION_SENT, SESSION_OPENED, SESSION_COMPLETED, SESSION_DECLINED, SESSION_REMINDED, SESSION_CANCELLED ["PACKAGE_COMPLETED", "PACKAGE_DECLINED"]
Free-text label for the endpoint.
"Production CRM sync"
Whether to start delivering straight away. Defaults to true.
true
Response
Success
Show child attributes
Show child attributes
Was this page helpful?

