Skip to main content

Set up entity hooks

Setting up an entity hook involves three steps:

  1. Configure a notification channel.
  2. Create an entity hook action.
  3. Implement the logic to process the hook and respond.

1. Configure a notification channel

Hooks send notifications through the specialized entity feed. To receive these notifications, configure a notification channel by sending a POST request with the endpoint details.

Here's an example for an HTTP notification channel:

np notification channel create \
--body '{
"source": ["entity"],
"nrn": "organization=1:account=2:namespace=3",
"type": "http",
"configuration": {
"url": "https://yourdomain.com/url-you-configured"
}
}'

For more channel types and delivery options, see the Notifications documentation.

2. Create an entity hook action

An entity hook action declares that you want to receive notifications for a specific event on an entity type. Create an entity hook action with the event and scope you want to subscribe to:

np entity-hook action create \
--body '{
"nrn": "organization=1:account=2:namespace=3:application=4",
"entity": "scope",
"action": "scope:create",
"dimensions": {
"environment": "staging",
"country": "us"
},
"when": "before",
"type": "hook",
"on": "create"
}'

Required parameters:

  • entity: The type of entity the hook applies to (application, scope, deployment).
  • action: The event to subscribe to (for example, application:create, scope:write, deployment:delete).
  • when: Whether the hook runs before or after nullplatform's internal processing.
  • type: The nature of the hook. Currently only hook is supported.
  • on: The lifecycle event that triggers the hook: create, update, or delete.

See the Entity hook API for the full parameter reference.

3. Implement hook processing

Once the hook action is configured, nullplatform starts sending notifications to your channel. Each notification carries a callback_url that points to the hook request: the record of that firing, which you can read at any time and respond to once your logic has run. Each notification has this format:

POST https://yourdomain.com/url-you-configured
{
"id": "1180cd02-1c36-4274-8e7a-4483b87e8f2e",
"source": "entity",
"event": "scope:create",
"created_at": "2025-02-13T14:20:43.088Z",
"notification": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"entity": "scope",
"entity_id": "5",
"nrn": "organization=1:account=2:namespace=3:application=4:scope=5",
"callback_url": "https://api.nullplatform.com/entity_hook/550e8400-e29b-41d4-a716-446655440000",
"type": "hook",
"when": "before",
"on": "create"
}
}

Responding to a hook

note

You need an ops role to perform this action.

After processing the hook, send a PATCH request to the callback_url from the notification:

PATCH callback-url
{
"status": "success",
"messages": [
{
"level": "info",
"message": "Information from the hook",
"timestamp": 1740406453123
},
{
"level": "warning",
"message": "Warning report",
"timestamp": 1740406527890
},
{
"level": "error",
"message": "The hook has failed",
"timestamp": 1740406604567
}
]
}

The status field controls how nullplatform handles the outcome:

StatusDescription
successHook logic executed successfully. The entity operation proceeds.
failedOperation failed entirely. The entity enters an error state.
recoverable_failurePartial failure. The entity remains valid but some changes may not have been applied. Relevant for update hooks.
cancelledEntity operation halted because conditions were not met.

The messages array is optional. Include it to give developers visibility into the hook's execution results.

Updating the entity from the hook

A before-hook can also hand data back to the entity it's gating. Add a callback_body object to the same PATCH request. When nullplatform resumes the entity operation, it merges those fields into the update it sends to the entity.

PATCH callback-url
{
"status": "success",
"callback_body": {
"repository_url": "https://github.com/my-org/my-service",
"tags": {
"provisioned_by": "platform-hook"
}
}
}

For example, a before-hook on application:create can decide which repository the application lives in. The application is then created in the repository your hook chose, not in the one the developer typed.

Keep these rules in mind:

  • callback_body accepts any field the entity's update endpoint accepts. There's no fixed list: whatever you'd send in a PATCH to that entity works here.
  • Fields nullplatform sets itself win. The entity status that moves the operation forward can't be overridden from callback_body. You can add fields, but you can't change how nullplatform resumes the entity.
  • callback_body must be a JSON object. Anything else is rejected with a 400, and the hook stays pending so you can retry.
  • It's stored with the hook request and returned when you read the hook request, so you can always check what a hook handed back.
  • It applies to whatever update runs for the status you send. Most hooks use it with success, but the merge also happens for failed, recoverable_failure, and cancelled.

Optional: filter which events reach your endpoint

By default, the hook fires on every matching event for the entity, action, and dimensions you set. If you want to react only to some of those events (for example, only when a deployment fully switches traffic, or only when a scope is being stopped), you don't filter the hook itself. You filter the notification channel that the hook delivers through.

The hook stays generic; the channel decides which events get through. See Conditional firing for the filter syntax, supported operators, and worked examples.