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

# Entity-Level Filtering

> Subscribe to webhook events for specific challenges, achievements, or rewards instead of the whole organisation.

By default, a webhook subscription fires for **every** matching event across your organisation. Entity-level filtering lets you narrow delivery to specific entities — for example, only fire `challenge-completion` for one flagship challenge, or only fire `reward-claim` for a particular reward asset.

<Info>
  Entity filters are optional. If you omit them, the webhook fires for all entities in the organisation.
</Info>

## Why filter by entity?

* **Reduce handler load**: only process events your downstream system cares about.
* **Per-partner webhooks**: point different webhook endpoints at different challenges (e.g. one challenge powers a partner's co-marketing flow, the rest stay internal).
* **Avoid accidental fan-out**: when you subscribe to a broad event like `reward-distribution`, filters stop you from processing unrelated rewards.

## Configure a filter

Entity filters are set per subscription. In the admin panel, open a webhook config, select an event, and pick the entities from the dropdown:

Via the Admin API, add an `entityFilters` map on the subscription:

```bash theme={null}
curl -X PUT "https://{subdomain}.nudj.cx/api/v2/admin/webhooks/configs" \
  -H "x-api-token: YOUR_ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "url": "https://your-app.com/webhooks/nudj",
      "httpMethod": "POST",
      "isEnabled": true,
      "maxRetries": 3,
      "events": ["challenge-completion", "reward-claim"],
      "entityFilters": {
        "challenge-completion": ["65a0b1c2d3e4f5a6b7c8d9e0"],
        "reward-claim": ["65a0b1c2d3e4f5a6b7c8d9e1", "65a0b1c2d3e4f5a6b7c8d9e2"]
      }
    }
  ]'
```

<Note>
  Entity IDs must belong to entities visible to the token's organisation. Filtering by an ID from a different org is rejected.
</Note>

## Event → entity mapping

Different events key off different entity types:

| Event                                                      | Entity Type                            | `eventSourceId` on payload |
| ---------------------------------------------------------- | -------------------------------------- | -------------------------- |
| `challenge-started`, `challenge-completion`                | Challenge                              | Challenge ID               |
| `achievement-completion`                                   | Achievement                            | Achievement ID             |
| `reward-claim`, `reward-redemption`, `reward-distribution` | Reward                                 | Reward ID                  |
| `action-participation`                                     | Action                                 | Action ID                  |
| `auth.email`, `streak-extended`                            | *(not filterable — organisation-wide)* | N/A                        |

Check the [Event Catalog](/developer/webhooks/event-catalog) for the full list.

## Editing filters

Filters can be changed any time — changes take effect immediately for new events. Existing in-flight deliveries (already queued) finish using the filter state at the time they were enqueued.

## Related

<CardGroup cols={2}>
  <Card title="Event Catalog" icon="list" href="/developer/webhooks/event-catalog">
    Every event Nudj can fire and the entities it attaches to.
  </Card>

  <Card title="Implementation Guide" icon="code" href="/developer/webhooks/implementation">
    Build your handler to trust the filtered event stream.
  </Card>
</CardGroup>
