Receive webhooks
Register an HTTPS endpoint, verify each delivery's signature, and process events once.
Register an endpoint
Your token needs the webhooks:write scope. The address must be public and use HTTPS.
curl -X POST https://api.mytpe.app/api/ext/webhooks \
-H "Authorization: Bearer $MYTPE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/hooks/mytpe", "events": ["transaction.paid"] }'The response holds the signing secret. MyTPE shows it only once, so store it on your server. An
empty events list subscribes to every event.
Verify the signature
Each delivery has an X-Mytpe-Signature header:
X-Mytpe-Signature: t=1733745296,v1=5257a869e7ec...c12dv1 is the HMAC-SHA256 of {t}.{raw body}, keyed with your secret.
- Read the raw request body before parsing it.
- Compute the HMAC.
- Compare it to
v1in constant time. - Refuse the delivery if the values differ, or if
tis more than 5 minutes old.
[$t, $v1] = sscanf($_SERVER['HTTP_X_MYTPE_SIGNATURE'], 't=%d,v1=%s');
$body = file_get_contents('php://input');
$expected = hash_hmac('sha256', "{$t}.".$body, $webhookSecret);
if (! hash_equals($expected, $v1) || abs(time() - $t) > 300) {
http_response_code(400);
exit;
}Respond and process
- Answer with a
2xxstatus within 10 seconds. Do slow work after you answer. - Use the payload's
idto skip events you've already processed, because a delivery can arrive more than once.
A non-2xx answer, a redirect or a connection error is retried, up to 5 attempts in all, after 10
seconds, 1 minute, 5 minutes and 15 minutes. MyTPE doesn't follow redirects.
To inspect attempts, call GET /webhooks/{id}/deliveries. To send one again, call
POST /webhooks/{id}/deliveries/{did}/redeliver.
Rotate the signing secret
Call POST /webhooks/{id}/regenerate-secret. The old secret stops working immediately, so deploy the
new one straight away.
For the payload format, see Webhook events.