Webhooks
Pro planWebhooks let Falcon tell your own systems when a return changes. Each time a matching event happens, Falcon sends a JSON message to an https address you choose. Use them to update an ERP, a warehouse tool, a helpdesk or your own reporting.
Every message is signed with your store's client secret, so your receiver can check that it really came from Falcon.
Add a webhook
- In Falcon, open Integrations and choose the Webhooks tab.
- Click Create webhook.
- Enter the Endpoint URL. It must be a public https address, for example
https://example.com/webhooks/returns. - Under Events, tick the events you want to receive. Return request created is ticked for you.
- Optional: under Condition, tick solutions or shipping methods to only send for those requests. Leave everything empty to send for all requests.
- Click Create.
The new webhook appears in the table with its URL, Created time, Event list and Condition (or All requests). The switch in the Action column turns it on and off.
Send a test first
Open the ⋯ menu on a row and choose Send test. Falcon sends a small test message and shows the result, for example "Test delivered (HTTP 200)" or "Test failed: …". The test uses the same headers and signature as real events. Its event is test and its data holds only a short message.
Endpoint rules
| Rule | Detail |
|---|---|
| Protocol | https only |
| Address | Must be public. Local, private-network, localhost, .local and .internal addresses are refused. |
| Length | Up to 500 characters |
| Credentials | Don't put a username or password in the URL |
| How many | Up to 10 webhooks per store |
Events
| Event key | Label in Falcon | Sent when |
|---|---|---|
request.created | Return request created | A new request is created on the return page or by staff in Falcon |
request.approved | Return request approved | A request is approved |
request.rejected | Return request rejected | A request is rejected |
request.received | Returned items received | The items are marked received |
request.resolved | Return resolved (refunded or exchanged) | The refund, store credit, gift card or exchange is issued |
request.archived | Return request archived | A request is archived |
Returns that come from Shopify admin, and status changes made there, show up in Falcon but don't send webhook events. Unarchiving a request doesn't send an event either.
The Condition filter checks the request's solution (for example Exchange item or Refund to store credit) and shipping method (for example Ship on your own). When you pick both, a request must match both.
What Falcon sends
Each delivery is an HTTP POST with a JSON body.
json
{
"id": "6f1c…",
"event": "request.approved",
"shop": "your-store.myshopify.com",
"created_at": "2026-10-27T10:15:00.000Z",
"data": {
"id": "clx…",
"rma": "R-10023",
"status": "approved",
"order_id": "gid://shopify/Order/123",
"order_name": "#1042",
"solution": "exchange",
"shipping_method": "ship_own",
"currency": "USD",
"refund_total_minor": 0,
"exchange_total_minor": 4500,
"customer_email": "customer@example.com",
"requested_at": "2026-10-26T18:02:11.000Z",
"items": [
{ "title": "Linen shirt", "variant_title": "M / Blue", "sku": "LS-M-BL", "quantity": 1, "reason": "Too small" }
]
}
}idat the top is unique per delivery. Use it to ignore duplicates.- Money is in minor units of the order currency (cents for USD).
4500means 45.00. statusis one ofpending_review,approved,rejected,resolvedorarchived.
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | Falcon-Returns-Webhooks/1.0 |
X-Falcon-Event | The event key, for example request.created |
X-Falcon-Webhook-Id | Same as id in the body |
X-Falcon-Hmac-SHA256 | The signature (see below) |
Delivery
- Your endpoint must answer with a 2xx status within 5 seconds.
- Redirects are not followed. Point the webhook at the final address.
- Falcon checks the address again when it sends. If it points to a private network, the delivery fails with "Endpoint is not a public address".
- Each event is sent once. A failed delivery is not retried, so log the
idand reconcile from Falcon if needed. - The table shows the last result under the URL: "Last delivery OK (HTTP 200)" or "Last delivery failed: …".
Verify the signature
The Client secret card on the Webhooks tab holds your store's secret. Use the eye button to show it and the copy button to copy it.
The X-Falcon-Hmac-SHA256 header is a base64 HMAC-SHA256 of the raw request body, made with that secret. Use the whole secret as the key, exactly as shown, including the fwhs_ at the start. Compute the same value on your side and compare. Always use the raw body, before any JSON parsing.
js
// Node.js with Express
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.FALCON_WEBHOOK_SECRET;
app.post("/webhooks/returns", express.raw({ type: "application/json" }), (req, res) => {
const expected = crypto.createHmac("sha256", SECRET).update(req.body).digest("base64");
const received = req.get("X-Falcon-Hmac-SHA256") ?? "";
const valid =
received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!valid) return res.status(401).end();
const event = JSON.parse(req.body.toString("utf8"));
// handle event.event and event.data here
res.status(200).end();
});Keep the secret private
Anyone with the secret can sign messages that look like Falcon's. Store it in your server's environment, not in code or a browser.
Change the secret
- On the Client secret card, click the refresh button (Regenerate secret).
- Confirm "Regenerate the secret? Existing receivers must be updated."
- Copy the new secret into every receiver.
You see "Client secret regenerated". The old secret stops working at once. Messages sent after this point are signed with the new one.
Turn off or delete a webhook
- To pause a webhook, turn off its switch.
- To remove it, open the ⋯ menu, choose Delete and confirm "Delete this webhook?".
After moving to a lower plan
Webhooks are part of the Pro plan. If your store moves to a lower plan, Falcon stops sending events. Your webhooks stay in the list so you can clean up: you can still turn them off and delete them. The Client secret card is hidden until you are back on Pro. Adding a webhook, turning one on and sending a test need the Pro plan again.