Skip to main content
Register an endpoint in your webhook settings. Create one setting for test mode and one setting for live mode. The two settings can use the same URL. MoonPay sends a webhook when a customer’s KYC status changes. MoonPay also sends a webhook when a buy transaction changes.

Requirements

Serve your endpoint over HTTPS. Return a 2xx status code within 5 seconds. A non-2xx response, a timeout, or a connection error is a failed delivery. MoonPay then retries the event. If the handler needs more than 5 seconds, return 200 first. Process the event after that response.

Verify the signature

MoonPay sends Moonpay-Signature-V2 on each request. Verify that header. The value has a timestamp and a signature, for example t=1492774577,s=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd. t is a Unix timestamp. s is a lowercase hex HMAC-SHA256. The signed text is the timestamp, a period, and the raw request body. The key is your webhook API key from the Developers page. MoonPay also sends Moonpay-Signature. Verify Moonpay-Signature-V2.
Verify the signature on your server. Keep the webhook API key off the client.
Read Moonpay-Signature-V2 from the request. Compute the digest from the raw body. Compare s to that digest with a constant-time check. Return 400 when the header is missing. Return 400 when t or s is missing. Return 400 when the signature differs. Keep the raw body for the HMAC. A JSON parser changes the bytes. The digest then does not match.

IP addresses

MoonPay sends webhooks from these IPv4 addresses:
  • 34.76.118.184
  • 34.77.238.249
  • 34.79.17.44
  • 34.89.242.107
  • 34.140.248.51
  • 34.159.58.44
  • 34.159.89.69
  • 35.246.202.26
Your network must permit traffic from these addresses. MoonPay does not send webhooks from IPv6 addresses. Outbound IPv6 support ended on July 15, 2026.

Delivery and retries

MoonPay retries a failed delivery. MoonPay stops after 10 attempts. MoonPay can deliver the same event more than once. A repeat delivery uses the same webhook-id header. A repeat delivery must not change the result of the first delivery. Events can arrive out of order. Arrival order does not show which payload is newer.

Events

Each event is an HTTP POST. The body is JSON. The content-type header is application/json.

Customer identity status updated

MoonPay sends customer.identity_status_updated when a customer’s KYC status changes. The Customer identity status updated page lists the fields. The body contains id, type, timestamp, and data. type is customer.identity_status_updated. webhook-id matches id. Compare timestamp to choose the newer event.

Transaction updated

MoonPay sends transaction_updated when a buy transaction changes. The transaction updated page lists the fields. Compare updatedAt on that payload to choose the newer transaction state.

Test a webhook

Use test mode before you use live mode. To receive a webhook on a machine that is not publicly reachable, forward a local port with ngrok. To inspect a payload without your own server, use webhook.site.