Repository navigation
feat: add webhook delivery retry - #66
Merged
Merged
Conversation
- Add the retry webhook delivery operation (POST /webhooks/{webhookId}/deliveries/{deliveryId}/retry) and RetryWebhookDeliveryResponse
- Add next_retry_at to WebhookDeliveryData and WebhookDeliveryListData
- Document that a delivery's payload, response body, response headers and error message are always included with a team API token
- Webhook delivery and regenerate-secret errors (401, 403, 429) can have either an ErrorMessage or an ApiError body
Co-Authored-By: Claude <noreply@anthropic.com>
Add webhooks().deliveries().retry(webhookId, deliveryId[, RequestOptions]), which sends a delivery's original payload to the webhook again now. It uses the team token and sends no request body. A 409 (webhook disabled, delivery not retryable, or a retry already in progress) is thrown as a ConflictException with the error code. Co-Authored-By: Claude <noreply@anthropic.com>
bjornftw
approved these changes
Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Adds
webhooks().deliveries().retry(webhookId, deliveryId[, RequestOptions]), next todeliveries().retrieve(...). It sends a webhook delivery's original payload to the webhook again now. The retry counts as a delivery attempt; if it fails with a retryable error, automatic retries continue. It needs the team token, sends no request body and takes noIdempotency-Key.The regenerated types also add
nextRetryAt()toWebhookDeliveryDataandWebhookDeliveryListData.Non-breaking. Suggested bump: minor (3.1.0 → 3.2.0).
API changes in the regenerated types
POST /webhooks/{webhookId}/deliveries/{deliveryId}/retry(team token, no body). 202 returns{message, delivery_id}. 409 withWEBHOOK_DISABLED,WEBHOOK_DELIVERY_NOT_RETRYABLEorWEBHOOK_DELIVERY_RETRY_IN_PROGRESS; also 401, 403, 404 and 429 (Retry-After).Operations.RETRY_WEBHOOK_DELIVERY, newRetryWebhookDeliveryResponserecord,webhooks().deliveries().retry(...). A 409 is thrown as the existingConflictException, withgetCode()returning the error code.next_retry_atonWebhookDeliveryDataandWebhookDeliveryListData: when the next automatic retry is due, ornullwhen none is scheduled. Optional and nullable.String nextRetryAt()record component andBuilder.nextRetryAt(...)on both records.payload,response_body,response_headersanderror_messageonWebhookDeliveryData: the description now says they are always included with a team API token.{message}or{error: {code, message, ...}}.Operationsupdated. The error parser already handled both shapes; new tests cover both on the retry endpoint.Every generated file also has a new spec header.
Compatibility note
WebhookDeliveryDataandWebhookDeliveryListDataare records, so their canonical constructors gain anextRetryAtargument. Code that callsnew WebhookDeliveryData(...)ornew WebhookDeliveryListData(...)directly (for example in test fixtures) must add the argument; builders are unaffected. Earlier minor releases shipped the same kind of change, so this is released as a minor.Usage
Checks
./gradlew checkGeneratedTypes: generated files up to date (206 files)./gradlew clean build --no-daemonon JDK 24: BUILD SUCCESSFUL (tests, javadoc, generated types check)./gradlew clean build --no-daemonon JDK 17, run as CI runs it: BUILD SUCCESSFUL; 93 tests, 0 failuresAutomatic-Module-Name: co.lettermintpresent, okhttp not bundledTeamApiTest:everyOperationIsReachablenow callsdeliveries().retryand covers all operationsretriesAWebhookDelivery: path, POST, team bearer token, no body, no content type, noIdempotency-Key, parsed 202 response, path-parameter validation, missing team tokenretryingADeliveryMapsErrorsToApiExceptions: 409WEBHOOK_DELIVERY_NOT_RETRYABLEasConflictExceptionwith its code; 429 with a{message}body plusRetry-After, and with an{error}body; 401; 404webhookDeliveriesExposeTheNextRetryAt: value,nulland absent, on retrieve and listNot run locally
./gradlew checkstyleMain checkstyleTest: these tasks do not exist in this project (the code-style workflow runs them with|| true).Suggested release tag
v3.2.0. It also covers the unreleased messages resend and per-email batch idempotency keys.🤖 Generated with Claude Code