Web Hooks
Receive results from long-running tasks without polling.
Registration
Add endpoints in the Findustry AI Portal, under the user menu › Settings ›
Developers › Webhooks. Registration sends a test webhook:ping.
Events
Chargebacks
| Event | Trigger | Data |
|---|---|---|
chargeback:copilot
|
Copilot success or error | Agent Recommendation response |
chargeback:letter
|
Response letter success or error |
id, responseLetter, and status
|
Payments
data matches Read Payment at delivery time.
| Event | Trigger |
|---|---|
payment:succeeded |
A card sale is captured, or a bank account debit is accepted |
payment:declined |
A card sale or a bank account debit is declined |
payment:voided |
A payment is voided before it settles |
payment:refunded |
A refund succeeds, once for each refund |
payment:settled |
A bank account debit settles |
payment:returned |
A bank account debit is returned |
Statements
Web hooks only trigger on statements initiated by API.
| Event | Trigger | Data |
|---|---|---|
statement:processed
|
Statement processing completes or fails | Statement Results response |
Delivery
Each delivery is an HTTP POST with a JSON body.
POST {{ webhook_url }}
Content-Type: application/json
X-Webhook-Signature: sha256={{ signature }}
{
data: {
// …
},
metadata: {
attempt: Number,
event: String,
id: String,
timestamp: Number,
type: "webhook",
webhook: String
}
}
| Field | Type | Description |
|---|---|---|
attempt |
Number (integer) | Delivery attempt count, starting at 1 |
event |
String | Event name, see Events |
id |
String (uuid) | Event identifier, unchanged across attempts for idempotency |
timestamp |
Number (milliseconds) | Attempt time. Changes with each attempt |
type |
String | Value webhook |
webhook |
String (uuid) | Endpoint receiving delivery |
Delivery is at least once. Use metadata.id to discard duplicates.
Outbound IP Addresses
Allow web hooks from these addresses:
3.220.86.1933.227.155.20518.214.229.18452.4.144.154
Signature Verification
X-Webhook-Signature is sha256= followed by the hex
HMAC-SHA256 of the raw request body, keyed by the signing secret.
import { createHmac, timingSafeEqual } from "node:crypto";
function verifySignature({ body, secret, signature }) {
const expected =
"sha256=" + createHmac("sha256", secret).update(body, "utf8").digest("hex");
return (
signature.length === expected.length &&
timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
);
}
Acknowledgment
| Code | Description | Result | Retried |
|---|---|---|---|
2XX |
Success | Delivered | No |
401 |
Unauthorized | Failed authentication | No |
429 |
Too many requests | Rate limited | Yes, with backoff |
5XX |
Server error | Receiver failed | Yes, with backoff |
504 |
Gateway Timeout | No response after 15 seconds, or unreachable host |
Yes, with backoff |
* |
Unknown error | Client error, including 3XX |
No |
Retries
Retries begin 30 seconds after the first failure and stop one hour after the first attempt. The Findustry AI Portal shows recent deliveries and results.
Errors
Failed tasks send the same event with an error in data.
{
data: {
id: String,
message: String,
status: "error"
}
}