---
title: "From flow.* to payment.flow.*"
description: "The webhook filter `flow.*` is now a 400. Replace it with `payment.flow.*`. No event delivery changes, because `flow.*` never matched anything."
source: https://docs.thru.la/migrations/flow-wildcard-to-payment-flow.md
html: https://docs.thru.la/migrations/flow-wildcard-to-payment-flow
index: https://docs.thru.la/llms.txt
---
# From `flow.*` to `payment.flow.*`

The webhook filter `flow.*` is now a 400. Replace it with `payment.flow.*`. No event delivery changes, because `flow.*` never matched anything.

| | |
| --- | --- |
| Changed | 2026-09-21 |
| Effort | Minutes. One string, in one place. |
| Changelog entry | [The flow.* webhook filter is refused — use payment.flow.*](https://docs.thru.la/changelog#2026-09-21-flow-wildcard-removed) |

---

## Do you need this?

Only if something you own **writes** a webhook subscription whose `eventTypes` contains the literal
string `flow.*`. That is: provisioning code, a Terraform-ish setup script, a seed fixture, or a
saved endpoint you are about to edit in the console.

```bash
grep -rn '"flow\.\*"\|flow\.\*' --include='*.ts' --include='*.js' --include='*.json' .
```

No hits → nothing to do.

## The change

```diff
  await fetch('https://api.thru.la/v1/webhooks', {
    method: 'POST',
    headers: { 'x-api-key': process.env.THRU_API_KEY, 'content-type': 'application/json' },
    body: JSON.stringify({
      url: 'https://example.com/hooks/thru',
-     eventTypes: ['payment.*', 'flow.*'],
+     eventTypes: ['payment.*', 'payment.flow.*'],
    }),
  });
```

Note that `payment.*` **already covers** `payment.flow.step`, `payment.flow.approved` and
`payment.flow.rejected`, because filters match by literal prefix. If you subscribe to
`payment.*` you can simply drop the entry rather than replacing it.

## What you will see

| | Before 2026-09-21 | After |
| --- | --- | --- |
| `POST /v1/webhooks` with `flow.*` | 200, endpoint saved | **400**, unknown filter |
| Events delivered to that endpoint | none, ever | none — nothing changed |

The filter was accepted on write and could never match on delivery: the flow family's event types
are `payment.flow.*`, and matching is a literal prefix test. So an endpoint filtered on `flow.*`
was already inert. This migration is about the **write** failing loudly instead of the **delivery**
failing silently.

## If you had an endpoint saved with `flow.*`

Open it in the console (Developers → Webhooks), replace the entry, and save. If you edit it through
the API, send the full `eventTypes` list you want — including the corrected entry — or the update
will be rejected for the stale one.

## Unchanged

`checkout.*` and `facilitator.*` are still valid, and were deliberately **not** narrowed to
`checkout.session.*` / `facilitator.payment.*`. If you use either, do nothing.
