Etsy API webhooks → a push notification on your phone
Etsy finally ships real webhooks. Point an order.paid endpoint at a Webhooky URL and your phone rings with a cash register the second someone buys – no server, no polling, no deploy.
What Etsy's webhooks actually give you
For years the only way to know about an Etsy sale was to poll getShopReceipts on a timer. That changed: Etsy rolled out webhooks for commercial apps in December 2025, and on 17 February 2026 opened full access to personal applications too. Four events are available, each delivered immediately:
order.paid– an order receives paymentorder.canceled– a seller initiates a cancelationorder.shipped– shipping information is created for a receiptorder.delivered– an order is marked as delivered
The important part, and the thing that surprises most people: the payload is tiny. Every event – regardless of type – carries exactly three fields:
{
"event_type": "order.paid",
"resource_url": "https://openapi.etsy.com/v3/application/shops/12345/receipts/67890",
"shop_id": 12345
}
No buyer, no item title, no price. Etsy tells you that something happened and hands you a URL to ask what. That design decision is what makes the next part so short.
The two-minute version: no server at all
A Webhooky endpoint is just a URL that accepts an HTTP POST and turns it into a push notification. Etsy needs "a publicly accessible callback URL that accepts POST requests". Those two halves fit together directly:
- In the Webhooky app, create an endpoint. Name it Etsy sale, set the message to something like “Someone bought from your shop” and pick the
cash_registerorka_chingsound. Copy the URL. - In Etsy's Developer Portal, open Manage your apps, use your app's dropdown and choose Go to Webhook portal.
- Click +Add Endpoint, paste your Webhooky URL, select
order.paidand hit Create.
That's it. Etsy POSTs its three fields, Webhooky ignores them, and because title and message are absent it falls back to the title and text you configured on the endpoint. You get an instant, distinctly-sounding notification per sale, on every device you've signed in on.
Two things worth knowing before you rely on it:
- Webhooky does not verify Etsy's signature. Etsy signs every delivery with
webhook-id,webhook-timestampandwebhook-signatureheaders, but a plain Webhooky endpoint accepts any POST. Anyone who learns your URL could trigger a notification. For a sales ping that's a nuisance at worst – if it matters to you, use the backend route below. - Etsy retries hard. Failed deliveries are retried immediately, then after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and once more after 10 hours. Webhooky always answers
200, including when you've hit the free tier's limit, so you never end up in a retry storm.
If you want the item name and the price
The notification above says "a sale happened". To say "Hand-thrown mug · €34.00" someone has to call resource_url, and that call needs your OAuth 2.0 access token – which means it has to happen somewhere you control. Receive Etsy's webhook in your own function, enrich it, then POST to Webhooky with an explicit title and message:
export async function onEtsyWebhook(req, res) {
res.sendStatus(200); // ack before doing work
const { event_type, resource_url } = req.body;
if (event_type !== "order.paid") return;
const receipt = await fetch(resource_url, {
headers: {
"x-api-key": process.env.ETSY_KEYSTRING,
Authorization: `Bearer ${await etsyAccessToken()}`,
},
}).then((r) => r.json());
const item = receipt.transactions?.[0]?.title ?? "an item";
const total = receipt.grandtotal;
await fetch(process.env.WEBHOOKY_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "🧶 Etsy sale!",
message: `${item} · ${total.amount / total.divisor} ${total.currency_code}`,
sound: "cash_register",
}),
});
}
Acknowledge first, enrich second – Etsy's retry schedule punishes slow endpoints, and a receipt lookup plus a push is easily slower than the delivery timeout.
Verifying the signature
If you take the backend route, verify before you trust. Etsy's scheme is standard symmetric signing: build webhook-id + "." + webhook-timestamp + "." + raw_body from the raw body before any JSON parsing, strip the whsec_ prefix from your signing secret and Base64-decode the remainder, compute HMAC-SHA256 over the signed content with that key, and Base64-encode the result. Accept if it matches any entry in webhook-signature. Reject anything whose webhook-timestamp is more than 300 seconds off your clock, so an old capture can't be replayed.
Not a developer? Use Zapier, Make or IFTTT
Etsy's webhook portal lives behind a developer app, which is more setup than most sellers want. Every major automation tool has an official Etsy integration that handles that part for you:
- Create your Webhooky endpoint and copy the URL, as above.
- Build a Zap with the trigger Etsy → New Transaction (“New Order” in Make and IFTTT).
- Add the action Webhooks → POST, paste your link, and send a JSON body:
{
"title": "🧶 Etsy sale!",
"message": "{{title}} · {{price}} {{currency}}"
}
Because the trigger already contains the order data, you get the item and the price without writing or hosting anything. The trade-off is latency: these integrations poll Etsy on a schedule, so expect minutes rather than seconds, and a task quota on the free plans.
Which route should you pick?
- Etsy webhook straight to Webhooky – seconds, zero infrastructure, no order details, no signature check. Best for "tell me the instant something sells".
- Etsy webhook → your function → Webhooky – seconds, full order details, signature verified. Best if you already run a backend.
- Zapier / Make / IFTTT – minutes, full order details, no code. Best if you're a seller, not an engineer.
More Etsy signals worth pushing
Once an endpoint exists, anything that can send a POST can reach your phone. order.shipped and order.delivered are already in Etsy's event list. Via an automation tool you can add a new review, a low-stock warning before a listing goes inactive, or a new favorite on a deliberately quieter sound. Give each one its own endpoint and its own sound and you can tell them apart without looking.
Why not just use the Etsy Seller app?
You can, and most sellers run both. Etsy's app is for managing the shop; Webhooky is for hearing it. Every event gets its own sound and vibration pattern, notifications arrive on all your devices at once, and each endpoint keeps its own history so you can scroll back through what fired and when. There's no account to create – install, create an endpoint, done.
Frequently asked questions
Does Etsy have webhooks?
Yes. Etsy released webhooks for commercial apps in December 2025 and extended full access to personal applications on 17 February 2026. The available events are order.paid, order.canceled, order.shipped and order.delivered.
What is in an Etsy webhook payload?
Three fields: event_type, resource_url and shop_id. There is no order, buyer or price data – you call resource_url with an OAuth token to fetch the receipt.
Can I get Etsy notifications without writing any code?
Yes. Point Etsy's webhook endpoint directly at a Webhooky URL and the notification uses the title, message and sound you configured in the app. If you'd rather avoid the Developer Portal entirely, use Zapier, Make or IFTTT instead.
Do I still need to poll the Etsy API?
Not for order events. Polling getShopReceipts is only needed for data Etsy has no event for, or to fetch the details behind an event you just received.