> ## Documentation Index
> Fetch the complete documentation index at: https://yieldxyz.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Real-time event notifications for transaction and balance changes

<Warning>
  **In Development** — The webhook system is currently being finalized. This documentation describes the target architecture and may be subject to change.
</Warning>

## Overview

Webhooks allow you to receive real-time notifications when events occur in your Yield.xyz integration. The system is designed for **reliability** with at-least-once delivery, automatic retries, and per-subject ordering.

<CardGroup cols={2}>
  <Card title="At-least-once delivery" icon="rotate">
    Guaranteed delivery with automatic retries
  </Card>

  <Card title="Per-subject ordering" icon="arrow-down-1-9">
    Sequence numbers for event ordering
  </Card>

  <Card title="HMAC signing" icon="signature">
    Cryptographic verification of payloads
  </Card>

  <Card title="Comprehensive diagnostics" icon="chart-line">
    Delivery status and error tracking
  </Card>
</CardGroup>

***

## Concepts

<AccordionGroup>
  <Accordion title="Endpoint">
    A customer destination URL + secret. This is where webhook payloads are delivered via HTTP POST.
  </Accordion>

  <Accordion title="Subscription">
    Rules determining **which events** an endpoint receives:

    * `events` (resources): e.g., `transaction`, `balance`, `position`
    * `actions`: e.g., `status_changed`, `amount_changed`
    * Optional filters: `yield_id`, `address`, `network`, `balance_type`
  </Accordion>

  <Accordion title="Event">
    An immutable record of "something happened" — the payload we deliver.
  </Accordion>

  <Accordion title="Delivery">
    A mutable work item representing one attempt to send one event to one endpoint.
  </Accordion>
</AccordionGroup>

***

## How It Works

<Steps>
  <Step title="Configure endpoint">
    Set up an endpoint URL and secret in your dashboard
  </Step>

  <Step title="Create subscriptions">
    Define which events to receive with optional filters
  </Step>

  <Step title="Events are emitted">
    When something happens (transaction confirmed, balance changed), an event is created
  </Step>

  <Step title="Deliveries are created">
    The system matches subscriptions and creates delivery work items
  </Step>

  <Step title="Dispatcher sends webhooks">
    A background worker claims deliveries and sends HTTP POST requests with HMAC signatures
  </Step>

  <Step title="Retries on failure">
    Failed deliveries are retried with exponential backoff
  </Step>
</Steps>

***

## Event Envelope

All webhook payloads use a consistent envelope format:

```typescript theme={null}
interface WebhookEventV1 {
  id: string;
  schema_version: 1;

  resource: 'transaction' | 'position' | 'balance' | 'rewards' | 'yield';
  action: 'status_changed' | 'state_changed' | 'amount_changed' | 
          'amount_increased' | 'sweep_eligible' | 'metadata_changed';
  type: string; // `${resource}.${action}`

  created_at: string; // ISO 8601
  project_id: string;

  subject: {
    yield_id?: string;
    position_id?: string;
    transaction_id?: string;
    address?: string;
    balance_type?: string;
    network?: string;
  };

  sequence: number;       // Monotonic per subject for ordering
  idempotency_key: string;

  data: Record<string, unknown>;
  previous?: Record<string, unknown>;
  changes?: Record<string, { from: unknown; to: unknown }>;
  meta?: {
    environment?: string;
    source?: string;
    trace_id?: string;
    request_id?: string;
  };
}
```

***

## Supported Events

| Resource      | Action             | Description                                                       |
| ------------- | ------------------ | ----------------------------------------------------------------- |
| `transaction` | `status_changed`   | Transaction status updated (pending → confirmed → success/failed) |
| `balance`     | `amount_changed`   | Balance amount changed                                            |
| `balance`     | `amount_increased` | Balance increased (deposits, rewards)                             |
| `position`    | `state_changed`    | Position lifecycle state changed                                  |
| `rewards`     | `sweep_eligible`   | Rewards ready to claim                                            |
| `yield`       | `metadata_changed` | Yield metadata updated (APY, TVL)                                 |

***

## Signing & Headers

Every webhook request is an HTTP **POST** with JSON body and these headers:

| Header              | Description              |
| ------------------- | ------------------------ |
| `X-Yield-Delivery`  | Unique delivery ID       |
| `X-Yield-Event`     | Resource type            |
| `X-Yield-Action`    | Action type              |
| `X-Yield-Timestamp` | Unix timestamp (seconds) |
| `X-Yield-Signature` | HMAC signature           |

### Signature Format

```
sha256=<hex(hmac(secret, timestamp + "." + rawBody))>
```

### Verification Example

```typescript theme={null}
import crypto from 'crypto';

function verifyWebhook(
  rawBody: string,
  timestamp: string,
  signature: string,
  secret: string
): boolean {
  const signaturePayload = `${timestamp}.${rawBody}`;
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(signaturePayload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
```

<Tip>
  Optionally reject old timestamps (e.g., older than 5 minutes) for replay protection.
</Tip>

***

## Delivery Semantics

### At-Least-Once Delivery

Receivers may see the **same event more than once**. Dedupe using:

* `event.id` (recommended)
* `X-Yield-Delivery` header

### Ordering

Events may arrive **out of order**. Use the `sequence` field (monotonic per subject) to:

* Reorder events
* Detect gaps

***

## Retry Policy

| Attempt | Wait Time  |
| ------- | ---------- |
| 1       | 1 minute   |
| 2       | 5 minutes  |
| 3       | 15 minutes |
| 4       | 1 hour     |
| 5       | 6 hours    |
| 6–10    | 24 hours   |

* **Success**: Any 2xx response
* **Failure**: Network errors, timeouts, non-2xx responses
* **Max attempts**: 10
* **After max**: Delivery marked as `dead`

***

## Delivery Lifecycle

| Status            | Description                           |
| ----------------- | ------------------------------------- |
| `pending`         | Created, ready for delivery           |
| `sending`         | Claimed by dispatcher, in-flight      |
| `delivered`       | Successfully delivered (2xx)          |
| `retry_scheduled` | Failed, will retry                    |
| `dead`            | Permanently failed after max attempts |

***

## Configuration

<Card title="Configure Webhooks" icon="gear" href="https://dashboard.yield.xyz/settings/webhooks">
  Set up webhook endpoints and subscriptions in your dashboard
</Card>

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Respond quickly" icon="bolt">
    Return 2xx within 15 seconds to avoid timeouts
  </Card>

  <Card title="Deduplicate" icon="copy">
    Use event.id to handle duplicate deliveries
  </Card>

  <Card title="Verify signatures" icon="shield-check">
    Always verify HMAC signatures before processing
  </Card>

  <Card title="Handle ordering" icon="arrow-down-1-9">
    Use sequence numbers to reorder events per subject
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/documentation/quickstart">
    Complete integration guide
  </Card>

  <Card title="Staking Extensions" icon="plug" href="/documentation/advanced-setup/staking-extensions/preferred-validator-network">
    Advanced staking options
  </Card>
</CardGroup>
