# Guide to Green Dot Webhooks: Features and Best Practices

Green Dot Embedded Finance webhooks notify your systems about banking-as-a-service activity: a transaction, an account update, an ACH transfer, a card update. If you're building on Green Dot's BaaS platform, webhooks are how you react to account events without polling.

This guide covers how Green Dot webhooks work, the push-authentication model (there's no single HMAC signature), the RequestId echo you must return, the retry behavior, and the best practices for production.

## What are Green Dot webhooks?

Green Dot Embedded Finance delivers webhooks to a partner-hosted endpoint that a Green Dot rep registers for you (there's no self-serve portal). The authentication model is push authentication, not a single HMAC signature: Green Dot authenticates its delivery to your endpoint via OAuth or mTLS.

## Green Dot webhook features

| Feature | Details |
| --- | --- |
| Configuration | Registered by your Green Dot rep, per event type (no self-serve UI) |
| Primary auth | OAuth (client_credentials grant, scope `post:webhook`); variants incl. mTLS/Certificate |
| Optional signature | `x-gd-signature` (algorithm/encoding/payload not public, get from your rep) |
| Required echo | Return the `x-GD-RequestId` header and respond 200/201 with a `responseDetails` JSON body |
| Retries | Hourly up to 24h on 5xx/timeouts/connection failures; must be enabled per-partner |
| Events | `eventType` values (`transaction`, `accountUpdated`, ...) |
| SDK | None |

## Common events

Green Dot event names are the `eventType` field values:

| Event | Fires when |
| --- | --- |
| `transaction` | A transaction occurs |
| `accountUpdated` | An account is updated |
| `achTransfer` | An ACH transfer occurs |
| `cardUpdate` | A card is updated |
| `billPayTransfer` | A bill-pay transfer occurs |
| `directDepositSwitch` | A direct deposit switch occurs |
| `provisioning` | A provisioning event occurs |

Branch on the `eventType` field.

## Setting up Green Dot webhooks

Endpoints are registered by your Green Dot rep, per event type, there's no self-serve UI. Configure the push-authentication method with them: OAuth (client_credentials, scope `post:webhook`) is primary, with variants including FormOAuth, PartnerOAuth, and Certificate (mTLS). Retries are opt-in per partner.

## Securing Green Dot webhooks

There's no single HMAC signature to verify. Instead, authenticate Green Dot's delivery:

### Push authentication (primary)

Green Dot authenticates itself to your endpoint using the method configured for your program, typically OAuth (`client_credentials`, scope `post:webhook`) or mTLS. Validate the OAuth token (or the client certificate) on each request before processing.

### The RequestId echo

Every delivery carries an `x-GD-RequestId` header. Your handler must echo it back and respond 200/201 with a `responseDetails` JSON body, this is how Green Dot confirms receipt.

```javascript
app.post("/webhook", express.json(), (req, res) => {
  // 1. Authenticate the delivery (OAuth token or mTLS client cert)
  if (!isAuthenticated(req)) {
    return res.sendStatus(401);
  }

  const requestId = req.headers["x-gd-requestid"];

  // 2. Echo x-GD-RequestId and return a responseDetails body
  res.setHeader("x-GD-RequestId", requestId);
  res.status(200).json({
    responseDetails: { code: "SUCCESS", message: "Received" },
  });

  processQueue.add({ eventType: req.body.eventType, body: req.body }); // async
});

```

### The optional x-gd-signature

Some programs also send an `x-gd-signature` header validated with a program-specific signing key, but Green Dot doesn't publish its algorithm, encoding, or canonical payload, obtain those from your Green Dot rep. Sample payloads show no signature header, so treat it as optional and program-gated.

## Green Dot webhook limitations and pain points

### No single HMAC signature

The Problem: There's no standard signature to verify. Authenticity rests on the push-authentication channel (OAuth or mTLS), and the optional `x-gd-signature` is undocumented publicly.

Why It Happens: Green Dot uses push authentication (the delivery authenticates itself) rather than payload signing.

Workarounds:

* Validate the OAuth token or mTLS certificate on every delivery; if you use `x-gd-signature`, get its spec from your rep.

How Hookdeck Can Help: Hookdeck gives you a dedicated ingestion URL and can enforce authentication in front of your endpoint, adding a consistent verification layer.

### You must echo x-GD-RequestId with responseDetails

The Problem: If you don't return the `x-GD-RequestId` header and a `responseDetails` JSON body with a 200/201, Green Dot may not consider the delivery received.

Why It Happens: Green Dot confirms receipt via the RequestId echo and structured response.

Workarounds:

* Echo `x-GD-RequestId` and return `responseDetails` on every acknowledgement.

How Hookdeck Can Help: Hookdeck can produce the required acknowledgement and durably queue the event, so your processing time is decoupled from the response contract.

### Rep-managed, program-gated configuration

The Problem: There's no self-serve setup, a Green Dot rep registers endpoints and configures auth per program, which slows changes.

Why It Happens: Green Dot manages BaaS integrations manually.

Workarounds:

* Coordinate with your rep for endpoint registration and auth configuration.

How Hookdeck Can Help: Hookdeck gives you a stable ingestion URL to register once, so your side of the configuration stays fixed.

### Retries and duplicates

The Problem: Retries run hourly up to 24 hours (when enabled), so the same event can arrive more than once.

Why It Happens: At-least-once delivery favors eventual delivery.

Workarounds:

* Enable retries with your rep, dedupe on an event id, and make side effects idempotent.

How Hookdeck Can Help: Hookdeck deduplicates deliveries at the edge. See our [guide to webhook idempotency](/webhooks/guides/implement-webhook-idempotency).

## Best practices

### Authenticate every delivery

Validate the OAuth token or mTLS certificate on each request before processing.

### Echo x-GD-RequestId with a responseDetails body

Return the `x-GD-RequestId` header and a `responseDetails` JSON body with a 200/201.

### Branch on eventType and dedupe

Route on the `eventType` field, and dedupe on an event id across the 24-hour retry window.

### Process asynchronously

Acknowledge, then defer work to a queue. See [why to process webhooks asynchronously](/webhooks/guides/why-implement-asynchronous-processing-webhooks).

## Conclusion

Green Dot Embedded Finance webhooks use push authentication (OAuth or mTLS), not a single HMAC, and require you to echo `x-GD-RequestId` and return a `responseDetails` body. An optional `x-gd-signature` exists but is undocumented publicly. Authenticate every delivery, honor the RequestId echo, branch on `eventType`, and dedupe.

[Hookdeck](https://hookdeck.com) authenticates deliveries, produces the required acknowledgement, deduplicates, and durably queues every event at the edge, so your app processes trustworthy events without minding the response contract.

[Get started with Hookdeck](https://dashboard.hookdeck.com/signup) for free and handle Green Dot webhooks reliably in minutes.