Skip to main content

Webhook Security

Response codes and retries

For webhook POSTs, TPA Stream listens for the following codes from your server and reacts accordingly:

CodeBehavior
200 / 2xxTPA Stream marks the POST successful. No retry.
406 (Not Acceptable)TPA Stream marks the POST consciously rejected. No retry.
Any other codeTPA Stream retries with exponential backoff for up to 4 hours.

The 406 semantics are a TPA Stream convention rather than a strict reading of RFC 7231. Use it when your endpoint received the post but deliberately chose to drop it (deduplication, business-rule mismatch, etc.) and you don't want TPA Stream to keep retrying.

TPAStream-Signature verification

Every webhook request includes a JWT signature in the TPAStream-Signature header. Use it to verify the request originated from TPA Stream and not some other party.

The signature can be verified using TPA Stream's SSH RSA public key, fetched from:

https://app.tpastream.com/keys

The JWT hashing algorithm is RS256.

We strongly recommend verifying the signature on every webhook endpoint you wire up. Decoding examples in most languages live at jwt.io. The library you choose must support RS256 (nearly all do) and should also support an exp check (though you can also do that yourself with a UTC timestamp).