A queued review was resolved
Delivered to the webhook URL configured in dashboard Settings when a human resolves a review.
Verify the signature against the raw request bytes. The Portreeve-Signature header carries sha256=<hex>, the HMAC-SHA256 of the exact body we sent, keyed with your webhook secret (whsec_…). If a JSON body parser runs before verification, re-serialised whitespace will make verification fail.
Deliveries retry with backoff until you return 2xx, so your handler must be idempotent — revoking an already-revoked account is a no-op, not an error. Respond 2xx quickly and do slow work (refunds, emails) asynchronously.
Headers
sha256=<hex> — HMAC-SHA256 of the raw request body, keyed with your webhook secret.
Payload
Always review.resolved. Switch on it rather than assuming — more webhook types will exist.
The id from the original verdict response.
approved: nothing to do. denied: revoke.
The verdict after resolution. A denial flips the original review to block.
The external_user_id from the original event — sent at verdict time or attached later via PATCH /v1/events/{id}. Resolve by this first.
The email from the original event, when one was sent. Fallback resolution handle if no external_user_id was ever bound — emails are mutable, so prefer the account id.