Conditional hook firing
By default, an entity hook fires on every matching event for its nrn, entity, action, and dimensions. If you want a hook to react only to some of those events (for example, only when a deployment is fully live), you don't filter the hook itself. You filter the notification channel that the hook delivers through.
The reason: hooks reach your code by going through a notification channel. nullplatform sends each hook event as a notification, and the channel decides whether to deliver it based on its filters field. So the same channel-side filtering you already use for Slack, HTTP, or agent notifications also works for entity hooks.
Common cases
- "Only run my deployment hook when the deployment switches traffic to 100%."
- "Only run my scope hook when the scope is being stopped."
- "Only run my application hook when the application is being imported from an existing repository."
How it works
When an entity event triggers a hook, nullplatform builds a notification with this shape and sends it to channels subscribed to the entity source:
{
"nrn": "organization=1:account=2:namespace=3:application=4:scope=5",
"action": "deployment:update",
"source": "entity",
"context": {
"entity": "deployment",
"action": "deployment:update",
"when": "after",
"on": "update",
"request_body": {
"status": "finalized",
"strategy_data": { "switched_traffic": 100 }
},
"tags": { ... }
}
}
The interesting part is request_body: it's the exact body of the operation that triggered the hook (the PATCH/POST/DELETE that nullplatform's framework intercepted).
Channel filters are evaluated against the context object, so when you write a filter expression you reference paths starting from inside context. No context. prefix needed. For example, the path to the request body is just request_body.<field>, not context.request_body.<field>.
What you can filter on
The fields you can match on are exactly the request body fields documented in the API reference for the operation that triggered the hook.
| Entity | on: create body | on: update body |
|---|---|---|
application | Create an application | Update an application |
scope | Create a scope | Update a scope |
deployment | Create a deployment | Update a deployment |
Any field shown in those request bodies is reachable inside request_body.<field>, including nested fields via dot notation.
For the full filter operator reference ($eq, $in, $and, $or, $gte, $regex, dot notation, and more), see Notification filters. The syntax is shared across nullplatform notification channels.
Setting up a filtered hook
A filtered hook is two things: the hook action itself (so nullplatform knows to intercept the event) and a channel with the right filters (so only the events you care about get delivered).
1. Create the hook action
np entity-hook action create \
--body '{
"nrn": "<account nrn or namespace nrn>",
"entity": "deployment",
"action": "deployment:update",
"when": "after",
"type": "hook",
"on": "update"
}'
No filters field on the hook itself: that's intentional. The hook just declares interest in deployment:update events; the channel decides which ones get delivered.
2. Create a channel with filters
np notification channel create \
--body '{
"nrn": "<account nrn or namespace nrn>",
"source": ["entity"],
"type": "http",
"configuration": {
"url": "https://yourdomain.com/deployment-finalized"
},
"filters": {
"request_body.strategy_data.switched_traffic": 100
}
}'
Now the channel only receives events where the deployment's strategy_data.switched_traffic is exactly 100. Other deployment updates fire the hook internally, but the channel filters them out before delivery.
Examples
Only on full traffic switch
"filters": {
"request_body.strategy_data.switched_traffic": 100
}
Only on a finalized deployment
"filters": {
"request_body.status": "finalized"
}
Combine conditions
Fire only when the deployment is finalized or the rollout has shifted at least half the traffic:
"filters": {
"$or": [
{ "request_body.status": "finalized" },
{ "request_body.strategy_data.switched_traffic": { "$gte": 50 } }
]
}
Filter on context fields beyond the request body
Channel filters can also match on the rest of the context. For example, only react to update events, not create or delete:
"filters": {
"on": "update",
"when": "after"
}
Where to go next
- Entity hooks overview: before/after hooks, approvals interaction, and the response contract
- Notification filters reference: full operator list and syntax shared across nullplatform channels
- Notify when a deployment fully shifts traffic: worked tutorial using the pattern from this page