Gareth Wilson Gareth Wilson

Guide to eBay Webhooks: Features and Best Practices

Published


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

FeatureDetails
ConfigurationDeveloper portal (Application Keys > Alerts and Notifications) or the Notification API
Endpoint challengeGET with challenge_code; return SHA-256 of challengeCode + verificationToken + endpoint
Signature headerx-ebay-signature (base64 JSON: alg, kid, signature, digest)
Signature schemeECDSA over the raw body; public key via getPublicKey by kid
Public keyGET /commerce/notification/v1/public_key/{public_key_id} (cache ~1 hour)
Acknowledgement2xx within 24h or the app keyset can be disabled
SDKevent-notification-nodejs-sdk (official Node listener)

Common topics

eBay notification topics use uppercase IDs. The two you're most likely to handle:

TopicFires when
MARKETPLACE_ACCOUNT_DELETIONA user requests account/data deletion (compliance-mandated to handle)
AUTHORIZATION_REVOCATIONA 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 endpoint string.

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.


Gareth Wilson

Gareth Wilson

Product Marketing

Multi-time founding marketer, Gareth is PMM at Hookdeck and author of the newsletter, Community Inc.