import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; import { type NormalizedClientOptionsWithAuth } from "../../../../BaseClient.js"; import * as core from "../../../../core/index.js"; import * as Hedra from "../../../index.js"; export declare namespace WebhooksClient { type Options = BaseClientOptions; interface RequestOptions extends BaseRequestOptions { } } /** * Configure, test, verify, and inspect outbound webhooks. * * **Delivery and retries.** Delivery is at-least-once. A `2xx` from your endpoint is success; anything else — including a redirect, which is never followed — is retried. Hedra makes up to **12 attempts over approximately 6 hours**, backing off 10s, 30s, 90s, 4m30s, 13m30s, 40m30s, then hourly. An endpoint that is unreachable for the whole window is marked `FAILED` and is not retried again; replay it with `POST /webhooks/deliveries/{job_id}/redeliver`. Two failures are permanent and stop the ladder immediately: a URL that resolves to a blocked address range, and a redirect pointing at one. * * Because the retry window is bounded, respond quickly and do your own processing asynchronously — acknowledge with a `2xx` first. * * **Deduplication.** Key on **`X-Hedra-Webhook-Id`**. It identifies the *event* — it is the job's own id, and it is byte-identical across every retry and every replay. Do **not** hash the request body: each attempt re-signs the output URL, so the body legitimately differs between attempts of the same event and a body hash would treat every retry as new. * * Each POST also carries `X-Hedra-Webhook-Attempt` (1-based, informational) and **`X-Hedra-Webhook-Redelivery`** (`true` / `false`). Redelivery is the exception to deduplication: when it is `true`, an operator asked for this event to be sent again — process it even if you have already recorded that id, because that request is the whole reason it was sent. * * **Inspecting deliveries.** `GET /webhooks/deliveries` reports each delivery's cumulative `attempts`, its latest outcome (`status`, `last_response_status`, `last_error`), and its replay history: `redelivery_count` counts operator replays, and `redeliveries` archives the outcome each replay superseded — a replay re-sends on the same delivery record and never erases the previous result. Each entry's `attempts` value is the cumulative total when that replay was requested, so the per-cycle attempt counts (and any total beyond the 12-attempt ladder) can be read off the record directly. * * **Why a delivery failed.** `last_error` — on the delivery and on every archived replay entry — is the same error envelope a failed job returns from `GET /jobs/{job_id}`, not a free-text diagnostic. Its `code` comes from the one error vocabulary this API uses, narrowed for delivery to this set: * * | `code` | Means | * | --- | --- | * | `DEADLINE_EXCEEDED` | Your endpoint did not respond before the delivery timeout. | * | `UNAVAILABLE` | Your endpoint could not be reached (DNS, TLS, or connection failure) or answered `5xx` — or redirected, which is never followed. | * | `RESOURCE_EXHAUSTED` | Your endpoint answered `429`. | * | `UNAUTHORIZED` | Your endpoint answered `401`. | * | `PERMISSION_DENIED` | Your endpoint answered `403`. | * | `NOT_FOUND` | Your endpoint answered `404`. | * | `INVALID_ARGUMENT` | Your endpoint answered some other `4xx`. | * | `FAILED_PRECONDITION` | The URL is not a permitted webhook target — it resolves to a blocked address range, or redirects to one. Fix the URL; replaying will not help. | * | `INTERNAL` | Hedra could not build the payload. | * | `UNKNOWN` | No classification is available, including for deliveries that failed before this field became structured. | * * `retryable` describes the condition, not what Hedra did: every non-2xx response is retried on the ladder above, so it answers whether replaying the delivery is likely to help. The `message` is a fixed summary — your endpoint's URL, address, headers, credentials, and response body are never echoed back, so treat your own logs, not this field, as the record of what your endpoint returned. * * **Verifying a delivery.** Every request carries `X-Hedra-Webhook-Signature`, a hex-encoded ed25519 signature over a canonical string of **five newline-separated fields, in this order**: * * ``` * {X-Hedra-Webhook-Timestamp} * {X-Hedra-Webhook-Id} * {X-Hedra-Webhook-Event} * {X-Hedra-Webhook-Redelivery} * {sha256 hex digest of the raw request body} * ``` * * Rebuild that string from the request you received, verify it against the key from `GET /webhooks/public-key`, and reject the delivery if the timestamp is more than 5 minutes old. Hash the body **exactly as received**, before any JSON parsing or re-serialization. * * The signature deliberately covers the deduplication id and the redelivery flag, not just the body — both of them decide whether you process a duplicate, so an unsigned copy of either would let anyone who captured a delivery replay it past your idempotency check. Verify *before* you act on any header. `X-Hedra-Webhook-Attempt` is outside the signature and is informational only; do not branch on it. */ export declare class WebhooksClient { protected readonly _options: NormalizedClientOptionsWithAuth; constructor(options?: WebhooksClient.Options); /** * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.getPublicKey() */ getPublicKey(requestOptions?: WebhooksClient.RequestOptions): core.HttpResponsePromise; private __getPublicKey; /** * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.UnauthorizedError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.getDefault() */ getDefault(requestOptions?: WebhooksClient.RequestOptions): core.HttpResponsePromise; private __getDefault; /** * @param {Hedra.WebhookDefaultUpdate} request * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.UnauthorizedError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.putDefault({ * url: "url" * }) */ putDefault(request: Hedra.WebhookDefaultUpdate, requestOptions?: WebhooksClient.RequestOptions): core.HttpResponsePromise; private __putDefault; /** * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.UnauthorizedError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.deleteDefault() */ deleteDefault(requestOptions?: WebhooksClient.RequestOptions): core.HttpResponsePromise; private __deleteDefault; /** * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.UnauthorizedError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.testDefault() */ testDefault(requestOptions?: WebhooksClient.RequestOptions): core.HttpResponsePromise; private __testDefault; /** * @param {Hedra.WebhooksListDeliveriesRequest} request * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.UnauthorizedError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.listDeliveries() */ listDeliveries(request?: Hedra.WebhooksListDeliveriesRequest, requestOptions?: WebhooksClient.RequestOptions): Promise>; /** * Replay a finished delivery: reset it to PENDING and re-fire the signed POST. * * 404 if the delivery isn't visible to the caller; 409 if a delivery for the * request is still in flight (a replay must not stack on it). The delivery is * re-validated (SSRF) and re-signed at send time, and the receiver dedupes on * ``X-Hedra-Webhook-Id``, so a replay is safe. * * The webhook id is stable across the original and every replay, because it * identifies the event. Every attempt of a replayed cycle therefore also carries * ``X-Hedra-Webhook-Redelivery: true`` — without it a receiver doing exactly what * our guidance says (dedupe on the id) would silently discard the replay, which is * the one case where the duplicate is the point. * * @param {string} job_id - The job's id (`job_`). * @param {Hedra.WebhooksRedeliverRequest} request * @param {WebhooksClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Hedra.BadRequestError} * @throws {@link Hedra.UnauthorizedError} * @throws {@link Hedra.ForbiddenError} * @throws {@link Hedra.NotFoundError} * @throws {@link Hedra.TooManyRequestsError} * @throws {@link Hedra.InternalServerError} * @throws {@link errors.HedraError} * @throws {@link errors.HedraTimeoutError} * * @example * await client.webhooks.redeliver("job_id") */ redeliver(job_id: string, request?: Hedra.WebhooksRedeliverRequest, requestOptions?: WebhooksClient.RequestOptions): core.HttpResponsePromise; private __redeliver; }