Guide to eBay Webhooks: Features and Best Practices
eBay notifications (eBay's webhooks) notify your application about account and authorization events: a user requests marketplace account deletion, an authorization is revoked. If you sell or build on eBay, handling these correctly, especially Marketplace Account Deletion, is a compliance requirement, not just a nice-to-have.
This guide covers how eBay notifications work, the mandatory endpoint challenge, how to verify the ECDSA message signature, and the best practices for production.
What are eBay webhooks?
eBay's Notification API delivers HTTP POSTs to a destination endpoint you register, each signed with an ECDSA message signature. Before eBay sends any notifications, it validates your endpoint with a challenge it expects you to answer with a specific hash. Then every notification carries an x-ebay-signature you verify using a public key fetched from eBay by key ID.
eBay webhook features
| Feature | Details |
|---|---|
| Configuration | Developer portal (Application Keys > Alerts and Notifications) or the Notification API |
| Endpoint challenge | GET with challenge_code; return SHA-256 of challengeCode + verificationToken + endpoint |
| Signature header | x-ebay-signature (base64 JSON: alg, kid, signature, digest) |
| Signature scheme | ECDSA over the raw body; public key via getPublicKey by kid |
| Public key | GET /commerce/notification/v1/public_key/{public_key_id} (cache ~1 hour) |
| Acknowledgement | 2xx within 24h or the app keyset can be disabled |
| SDK | event-notification-nodejs-sdk (official Node listener) |
Common topics
eBay notification topics use uppercase IDs. The two you're most likely to handle:
| Topic | Fires when |
|---|---|
MARKETPLACE_ACCOUNT_DELETION | A user requests account/data deletion (compliance-mandated to handle) |
AUTHORIZATION_REVOCATION | A user revokes your app's authorization |
eBay has additional topics; validate exact uppercase topicId strings against a live getTopics call before building a larger event table, since names beyond these two vary.
Setting up eBay webhooks
Configure notifications in the developer portal under Application Keys > Alerts and Notifications (for Marketplace Account Deletion), and for other topics via the Notification API (topics + destinations + subscriptions). Creating a destination triggers the endpoint challenge below.
Securing eBay webhooks
The endpoint-creation challenge
When you create a destination, eBay sends a GET https://<endpoint>?challenge_code=.... You must return HTTP 200 with JSON {"challengeResponse":"<hex>"}, where the hex is the SHA-256 hash of exactly challengeCode + verificationToken + endpoint, in that order. The verificationToken is a 32-80 character string you choose ([A-Za-z0-9_-]). The concatenation order is mandatory; get it wrong and the endpoint won't validate.
const crypto = require("crypto");
const VERIFICATION_TOKEN = process.env.EBAY_VERIFICATION_TOKEN; // 32-80 chars
const ENDPOINT = "https://your-app.example.com/webhook"; // exactly as registered
app.get("/webhook", (req, res) => {
const challengeCode = req.query.challenge_code;
const hash = crypto.createHash("sha256");
hash.update(challengeCode); // 1. challengeCode
hash.update(VERIFICATION_TOKEN); // 2. verificationToken
hash.update(ENDPOINT); // 3. endpoint (order is mandatory)
res.status(200).json({ challengeResponse: hash.digest("hex") });
});
Verifying the ECDSA message signature
Each notification carries an x-ebay-signature header: a base64-encoded JSON object with alg, kid, signature, and digest. Use the kid to fetch the matching public key via the Notification API's getPublicKey (GET /commerce/notification/v1/public_key/{public_key_id}), then verify the signature over the raw request body. Cache the public key (~1 hour). Because this is fiddly ECDSA, prefer eBay's official Node listener SDK, event-notification-nodejs-sdk, which handles the signature verification and public-key caching (keyed by kid) for you:
// Using event-notification-nodejs-sdk (recommended)
const { validateSignature } = require("ebay-event-notification-sdk"); // per SDK docs
app.post("/webhook", express.raw({ type: "application/json" }), async (req, res) => {
const isValid = await validateSignature(
req.body, // raw body
req.headers["x-ebay-signature"],
{ /* app credentials / config per the SDK */ }
);
if (!isValid) return res.sendStatus(412); // eBay expects rejection on bad signature
res.sendStatus(200); // 2xx acknowledges
processQueue.add(JSON.parse(req.body)); // process asynchronously
});
If you verify manually, base64-decode x-ebay-signature to read alg/kid/signature, fetch and cache the public key by kid, and verify the ECDSA signature over the raw body.
eBay webhook limitations and pain points
The challenge-hash order is strict
The Problem: The endpoint challenge hashes challengeCode + verificationToken + endpoint in exactly that order. Any other order (or a mismatched endpoint string) fails validation and the destination won't be created.
Why It Happens: eBay defines a precise concatenation to prove you hold the verification token and control the endpoint.
Workarounds:
- Hash the three values in the mandated order, and use the exact registered
endpointstring.
How Hookdeck Can Help: Hookdeck can answer the eBay challenge and verify signatures at the edge, so your application receives pre-verified events without reproducing the hash contract.
ECDSA with a fetched public key
The Problem: Signature verification is asymmetric: decode the header JSON, fetch a public key by kid, and verify ECDSA over the raw body. It's easy to get the encoding or caching wrong.
Why It Happens: eBay uses ECDSA message signatures with ID-referenced public keys.
Workarounds:
- Use the official
event-notification-nodejs-sdk, which handles verification and caching.
How Hookdeck Can Help: Hookdeck verifies the ECDSA signature at the edge, so your app receives pre-verified events without embedding the crypto.
Account deletion is compliance-critical
The Problem: MARKETPLACE_ACCOUNT_DELETION must be handled, and failing to acknowledge notifications (2xx within 24h) can get your app keyset disabled, breaking your entire integration.
Why It Happens: eBay mandates deletion handling and enforces it via keyset status.
Workarounds:
- Ensure the endpoint reliably returns 2xx and actually processes deletions.
- Monitor keyset health and alert on delivery failures.
How Hookdeck Can Help: Hookdeck reliably accepts and acknowledges eBay's notifications and durably queues them, so a downstream hiccup doesn't cascade into a disabled keyset. Its observability surfaces failures fast.
Duplicates and topic naming
The Problem: The same notification can arrive more than once, and topic IDs beyond the core two vary, so a hardcoded topic list can miss events.
Why It Happens: At-least-once delivery plus an evolving topic catalog.
Workarounds:
- Dedupe on the notification ID, and validate topic strings against
getTopics.
How Hookdeck Can Help: Hookdeck deduplicates deliveries at the edge, so retries don't double-process. See our guide to webhook idempotency.
Best practices
Answer the challenge in the exact order
Hash challengeCode + verificationToken + endpoint (that order), return {"challengeResponse":"<hex>"} with a 200, and use the exact registered endpoint string.
Verify the ECDSA signature via the SDK
Use event-notification-nodejs-sdk to verify x-ebay-signature over the raw body and cache the public key by kid.
Acknowledge within the window, process asynchronously
Return 2xx (well within 24h, ideally immediately) and defer work to a queue so keyset health is never at risk. See why to process webhooks asynchronously.
Handle account deletion reliably and dedupe
Treat MARKETPLACE_ACCOUNT_DELETION as compliance-critical, dedupe on the notification ID, and validate topics against getTopics.
Make eBay webhooks production-ready
Hookdeck answers the challenge, verifies the ECDSA signature, deduplicates, and durably queues every notification
Conclusion
eBay notifications require two things most webhooks don't: a precise endpoint challenge (SHA-256 of challengeCode + verificationToken + endpoint, in that exact order) and ECDSA signature verification using a public key fetched by kid. On top of that, Marketplace Account Deletion is compliance-critical and failing to acknowledge can disable your keyset.
Hookdeck answers the challenge, verifies the ECDSA signature, deduplicates, and durably queues every notification at the edge, so your app reliably processes verified, unique events and never risks its keyset over a downstream hiccup.
Get started with Hookdeck for free and handle eBay webhooks reliably in minutes.