Skip to main content
This is for the Yativo dashboard (app.yativo.com). It covers adding a Resend action to the webhook delivery log so a signed-in customer can redeliver an event to their current endpoint. The API itself is documented in Webhooks Guide → Resending an event. This file is only the frontend work: where the button lives, which calls to make, how to gate it by role, and how to handle the result.

What to add

Put this on the existing Webhooks → Delivery log (or Developers → Events) screen, not on the webhook URL settings page. Do not resend from the webhook URL / secret settings screen. Resend needs a delivery-log id, not the webhook UUID.

Auth

Dashboard calls use the signed-in person’s bearer token, same as the rest of the app:
Since 15 October 2026 the token only works from the dashboard origin. Do not call these endpoints with X-Api-Key from the browser. Omit Idempotency-Key on resend. The route is excluded from the idempotency fallback so the same event can be resent more than once. A global interceptor that always sends a new UUID per click is fine; a reused key is not needed here.

Permissions

Team members are swapped to the business owner for these routes, then checked against team permissions. A viewer who clicks Resend gets 403 Your team role is read-only; only GET requests are allowed. Hide the button instead of letting them hit that. Check before rendering:
Owners always can; you can skip the check when current_team_id is the caller’s own team and they are the owner.

Endpoints

Base URL: https://api.yativo.com/api in production, https://smtp.yativo.com/api on sandbox. {eventId} is the delivery log’s numeric id (for example 981). It is not payload.id, payload.payload.id, a deposit id, or the webhook UUID. per_page defaults to 10 if omitted. List filters (all optional, combine them): type also accepts the aliases event and transaction_type; transaction_id also accepts transactionId. Use the names in the table. Put a Transaction ID search and an Event type control (select or combobox) above the table. Suggested type options (family prefix unless noted): Typing the full event name (payout.updated, virtualcard.transaction.settlement) still works. crypto_deposit (older crypto event) is a separate exact name — it is not under crypto. Keep status as Delivered (success) / Failed (failed) / All. Example: find a failed deposit to resend:

List page

GET /v1/business/events/all returns the standard list envelope:
Suggested columns: You can highlight failed rows and still allow resend on successful ones (the customer may want a replay after they changed their handler). Resend a replay row the same way; {eventId} is always this row’s id. When this delivery is a resend, or the original event was resent later, resend looks like:
ip is the browser or server that clicked Resend, not a Cloudflare hop. via is dashboard, api_key, or admin — dashboard clicks are dashboard. Don’t put this object in the outbound webhook body — it is only on our log. user_agent is never returned. user_id is the business account. Don’t show it as a “customer” column in this UI.

Detail page

GET /v1/business/events/show/{eventId} returns one log in data. 404 with Webhook event not found means a bad id or another account’s event. Show:
  1. Status badge, HTTP code, time, destination URL.
  2. Event name from the payload (event.type, else event).
  3. Request payload as formatted JSON. Logged payloads are already scrubbed of secrets and internal fields (older logs may show fewer fields than were sent at the time).
  4. Endpoint response body (may be empty).
  5. If resend is present:
    • If original_event_id === id: Last resent by {by.name} at {at} from {ip}.
    • If original_event_id !== id: Replay of delivery {original_event_id}, queued by {by.name} at {at}. Link to that original.
  6. Resend in the header, with the same confirm + loading behaviour as the table.

Resend interaction

No body. 1. Confirm. The event is sent to whatever URL is registered now, signed with the current secret, even if url on the log is an old endpoint.
Resend this event to your current webhook URL? A new delivery attempt will be logged.
2. Disable the button while the request is in flight. One click → one queue. 3. Success (200):
Toast that message. Then:
  1. Reload the original row (or the current page). resend is written at click time, so Resent by can show before the new attempt exists.
  2. Optionally refresh again after 1–2s to pick up the new log row. Don’t poll in a tight loop. The new row may still be failed if their endpoint is down.
4. Treat as success only when HTTP is 2xx and status === "success". See API responses.

Errors


Frontend example

Example click handler:

Checklist

  • Resend lives on the delivery log list and detail, using log.id.
  • List has Transaction ID and Event type filters (transaction_id, type), plus Delivered/Failed (success / failed).
  • Button hidden without team.webhooks.manage (viewers never see it).
  • Confirm dialog before POST; button disabled while in flight.
  • Success toast uses data.message. Original row reloads immediately so Resent by appears; optional 1–2s refresh for the new attempt.
  • Replay rows (resend.original_event_id !== id) link back to the original delivery.
  • 400 no-endpoint links to webhook URL settings; disable Resend when GET /v1/business/webhook has no URL.
  • 404 / 403 don’t look like a server crash.
  • Event column reads payload["event.type"], else payload.event (gift cards).
  • No Idempotency-Key required; don’t block a second resend of the same row.
  • Detail (and optionally the table) shows resend.by, resend.at, and resend.ip when present.