From 647b97089cf3d5946df3b2c85a4bdab562f50ff8 Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Wed, 9 Sep 2026 16:39:52 -0300 Subject: [PATCH 1/3] feat(webhooks): add signing secret rotation endpoint Co-Authored-By: Claude Fable 5.1 --- examples/webhooks.rb | 5 +++++ lib/resend/webhooks.rb | 15 +++++++++++++++ spec/webhooks_spec.rb | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/examples/webhooks.rb b/examples/webhooks.rb index a66a245..899c50a 100644 --- a/examples/webhooks.rb +++ b/examples/webhooks.rb @@ -35,6 +35,11 @@ updated_webhook = Resend::Webhooks.update(update_params) puts "\nUpdated webhook: #{updated_webhook[:id]}" +# Rotate the webhook signing secret +rotated_webhook = Resend::Webhooks.rotate_signing_secret(webhook[:id]) +puts "\nRotated signing secret for webhook: #{rotated_webhook[:id]}" +puts "New signing secret: #{rotated_webhook[:signing_secret]}" + # List all webhooks webhooks = Resend::Webhooks.list puts "\nTotal webhooks: #{webhooks[:data].length}" diff --git a/lib/resend/webhooks.rb b/lib/resend/webhooks.rb index 30bd6b2..7ca6afe 100644 --- a/lib/resend/webhooks.rb +++ b/lib/resend/webhooks.rb @@ -182,6 +182,21 @@ def update(params = {}) Resend::Request.new(path, params, "patch").perform end + # Rotate the signing secret of a webhook + # + # Generates a new signing secret for the webhook. The previous secret stops validating immediately. + # + # @param webhook_id [String] The webhook ID + # + # @return [Hash] The webhook object containing id, object type, and the new signing_secret + # + # @example + # Resend::Webhooks.rotate_signing_secret("4dd369bc-aa82-4ff3-97de-514ae3000ee0") + def rotate_signing_secret(webhook_id) + path = "webhooks/#{webhook_id}/signing-secret/rotate" + Resend::Request.new(path, {}, "post").perform + end + # Remove an existing webhook # # @param webhook_id [String] The webhook ID diff --git a/spec/webhooks_spec.rb b/spec/webhooks_spec.rb index 0f47c32..c5ddce4 100644 --- a/spec/webhooks_spec.rb +++ b/spec/webhooks_spec.rb @@ -118,6 +118,27 @@ end end + describe "rotate_signing_secret" do + it "rotates the webhook signing secret" do + resp = { + "object": "webhook", + "id": "4dd369bc-aa82-4ff3-97de-514ae3000ee0", + "signing_secret": "whsec_yyyyyyyyyy" + } + request = instance_double(Resend::Request) + expect(Resend::Request).to receive(:new) + .with("webhooks/4dd369bc-aa82-4ff3-97de-514ae3000ee0/signing-secret/rotate", {}, "post") + .and_return(request) + expect(request).to receive(:perform).and_return(resp) + + result = Resend::Webhooks.rotate_signing_secret("4dd369bc-aa82-4ff3-97de-514ae3000ee0") + + expect(result[:object]).to eql("webhook") + expect(result[:id]).to eql("4dd369bc-aa82-4ff3-97de-514ae3000ee0") + expect(result[:signing_secret]).to eql("whsec_yyyyyyyyyy") + end + end + describe "list_event_attempts" do it "lists webhook event attempts with pagination" do request = instance_double(Resend::Request) From 101b9acb5b545074dbecb0657405fbc566d5b3de Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Thu, 10 Sep 2026 09:42:16 -0300 Subject: [PATCH 2/3] chore: bump version to 1.15.0 Co-Authored-By: Claude Fable 5.1 --- Gemfile.lock | 2 +- lib/resend/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ebe082f..dbd0dc6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - resend (1.14.0) + resend (1.15.0) base64 httparty (>= 0.22.0) diff --git a/lib/resend/version.rb b/lib/resend/version.rb index 4319330..7061a61 100644 --- a/lib/resend/version.rb +++ b/lib/resend/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Resend - VERSION = "1.14.0" + VERSION = "1.15.0" end From ef2ecbebcd396d27379bc91bf7b35691d0108fed Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Thu, 10 Sep 2026 10:52:06 -0300 Subject: [PATCH 3/3] docs(webhooks): note the 24 hour grace period after rotating the signing secret Co-Authored-By: Claude Fable 5.1 --- lib/resend/webhooks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resend/webhooks.rb b/lib/resend/webhooks.rb index 7ca6afe..43a7363 100644 --- a/lib/resend/webhooks.rb +++ b/lib/resend/webhooks.rb @@ -184,7 +184,7 @@ def update(params = {}) # Rotate the signing secret of a webhook # - # Generates a new signing secret for the webhook. The previous secret stops validating immediately. + # Generates a new signing secret for the webhook. The previous secret keeps working for 24 hours. # # @param webhook_id [String] The webhook ID #