Skip to main content

Notification events

Notification events record every notification sent through nullplatform channels.
Each event includes delivery data such as source, status, and timestamps, plus the full JSON payload that was transmitted.

Notification events help you:

  • Inspect which notifications were sent and to which channels.
  • Verify event payloads for debugging or auditing purposes.
  • Resend notifications if a channel fails or needs to be retried.

You can view and manage these events from the UI or through the Notification Events API.

Resending a notification event

You can resend a previously generated notification event to one or more channels. This creates a new event record with a unique ID while preserving the original payload.

Use the Resend a notification event endpoint to trigger the operation.

Example:

curl -L 'https://api.nullplatform.com/notification/:id/resend' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <token>' \
-d '{
"channel_ids": [
"123",
"234",
"345"
]
}'
  • If channel_ids is omitted, the notification will be resent to all configured channels.
  • If provided, it must be a non-empty array containing valid channel identifiers.
tip

This operation is useful for replaying missed notifications or re-sending events to a specific channel after fixing configuration or connectivity issues.

note

A status: failed on a notification event means the delivery to the channel failed, not that the underlying API operation failed. For example, a namespace creation that returned HTTP 200 can still produce a failed notification if the webhook endpoint timed out.

To confirm whether the original operation succeeded, check the status field inside the event payload itself.

Other notification event operations

In addition to resending, you can also list and inspect notification events. These endpoints let you view historical data and payloads for auditing or troubleshooting purposes.

  • List events: Retrieve all notification events for a given NRN and filter them by source or status.
  • Read an event: Retrieve detailed information about a specific event, including the original payload and delivery results.

You can perform these actions either through the UI or via the Notification Events API Reference.

Context payloads

Notification events deliver context data in a consistent JSON format, mirroring the structure of our API responses. Use this data to:

  • Apply filters using MongoDB-style queries.
  • Enrich third-party systems with entity metadata.
You need a secops role to read context data.

Payload structure by source

Each source produces a different payload shape. Here's what to expect at the top level:

SourceTop-level fieldsDescription
approvalapproval_id, approve_url, deny_url, requested_by, action, details, policy_detailsApproval request with the full entity hierarchy in details
serviceaction, id, name, slug, status, parameters, results, specification, service, tags, entity_nrnService action with specification and dimension context
auditentity_context, user_email, user_type, entity_data, entity, method, status, url, headers, request_bodyFull API interaction log with entity context and request details
entityid, source, event, created_at, notificationEntity lifecycle hook with a callback_url for response
parametersaction, details (contains parameter, application, namespace, account, organization)Parameter change event with resource hierarchy
telemetryaction, arguments (contains provider-specific fields like scope_provider)Telemetry event with provider context

Below are detailed examples for each source.

Approvals

The context data you receive follows the same structure as responses from our public API’s read endpoints. That also means you can expect each entity to include any associated metadata, if available.

The details object in the payload contains entities relevant to the specific approval request.

For more information about entity schemas, refer to our API reference.

Deployment

In a deployment approval, details.deployment matches the structure of a GET request to our deployments endpoint.

Payload example - Deployment
{
"approval_id": 1,
"approve_url": "https://api.nullplatform.com/approval/1/approve?token=xxx",
"deny_url": "https://api.nullplatform.com/approval/1/deny?token=yyy",
"requested_by": {
"user_id": 1,
"email": "alex.doe.developer@domain.com",
"first_name": "alex",
"last_name": "doe",
"avatar": null
},
"action": "deployment:create",
"details": {
"deployment": {
"id": 6,
"scope_id": 6,
"release_id": 7,
"status": "creating_approval",
"status_in_scope": "candidate",
"messages": [],
"parameters": [],
"strategy": "initial",
"strategy_data": {},
"created_at": "2025-03-18T14:09:33.412Z",
"updated_at": "2025-05-10T08:47:19.983Z",
"expires_at": "2025-05-18T08:47:19.984Z",
"created_by": 444,
"updated_by": null,
"deployment_token": "abc-3f9cb741-77ea-4c62-bd1a-58d9c2a1ef34",
"deployment_group_id": null,
"status_started_at": {
"creating_approval": "2025-03-24T19:15:38.298Z"
},
"nrn": "organization=1:account=2:namespace=3:application=4:scope=5:deployment=6",
"metadata": {}
},
"scope": {
"id": 6,
"name": "Production Argentina",
"metadata": {},
"type": "web_pool",
"asset_name": "main",
"application_id": 4,
"status": "active",
"slug": "production-argentina",
"domain": "kong-namespace-acme-test-app-production-argentina-ghebf.acme-corp-main.apps.io",
"requested_spec": {
"cpu_profile": "standard",
"memory_in_gb": 0.125,
"local_storage_in_gb": 8
},
"tier": "important",
"external_created": false,
"provider": "AWS:WEB_POOL:EC2INSTANCES",
"instance_id": null,
"updated_at": "2025-03-24T19:15:38.293Z",
"messages": [],
"profiles": [],
"capabilities": {
"continuous_delivery": {
"enabled": false
},
"logs": {
"throttling": {
"unit": "line_seconds",
"value": 1000,
"enabled": false
},
"provider": "cloudwatch_logs"
},
"metrics": {
"custom_metrics_provider": "cloudwatch_metrics",
"performance_metrics_provider": "cloudwatch_metrics"
},
"spot_instances": {
"target_percentage": 80,
"enabled": false
},
"auto_scaling": {
"cpu": {
"max_percentage": 40,
"min_percentage": 40
},
"instances": {
"max_amount": 10,
"min_amount": 2,
"amount": 1
},
"enabled": false
},
"memory": {
"memory_in_gb": 0.125
},
"storage": {
"storage_in_gb": 8
},
"processor": {
"instance": "",
"type": "cpu"
},
"visibility": {
"reachability": "account"
},
"health_check": {
"type": "http",
"path": "/health",
"configuration": {
"timeout": 2,
"interval": 5
}
},
"scheduled_stop": {
"timer": "3600",
"enabled": true
}
},
"tags": ["test", "stopped", "parameters_changes"],
"dimensions": {
"environment": "production",
"country": "argentina"
},
"runtime_configurations": [11, 22],
"domains": [],
"nrn": "organization=1:account=2:namespace=3:application=4:scope=5"
},
"release": {
"id": 7,
"semver": "0.0.1",
"build_id": 8,
"status": "active",
"application_id": 4,
"created_at": "2025-03-18T14:09:33.412Z",
"updated_at": "2025-05-10T08:47:19.983Z",
"nrn": "organization=1:account=2:namespace=3:application=4:scope=5:release=8",
"metadata": {}
},
"build": {
"id": 8,
"application_id": 4,
"commit": {
"id": "a93f1e6bd4c8fa705b2dcb197a3e4d8615c9ab32",
"permalink": "https://github.com/acme-corp/kong-namespace-acme-test-app/commit/a93f1e6bd4c8fa705b2dcb197a3e4d8615c9ab32"
},
"status": "successful",
"description": "wip",
"branch": "main",
"created_at": "2025-03-18T14:09:33.412Z",
"updated_at": "2025-05-10T08:47:19.983Z",
"nrn": "organization=1:account=2:namespace=3:application=4:build=8",
"metadata": {}
},
"application": {
"id": 4,
"name": "Acme Test App",
"status": "active",
"namespace_id": 3,
"repository_url": "https://github.com/acme-corp/kong-namespace-acme-test-app",
"slug": "acme-test-app",
"template_id": 9,
"auto_deploy_on_creation": false,
"repository_app_path": null,
"is_mono_repo": false,
"tags": {},
"nrn": "organization=1:account=2:namespace=3:application=4",
"metadata": {}
},
"namespace": {
"id": 3,
"name": "Kong namespace",
"account_id": 2,
"slug": "kong-namespace",
"status": "active",
"nrn": "organization=1:account=2:namespace=3",
"metadata": {}
},
"account": {
"id": 2,
"name": "main",
"organization_id": 1,
"repository_prefix": "acme-corp",
"repository_provider": "github",
"status": "active",
"slug": "acme-corp-main",
"nrn": "organization=1:account=2",
"metadata": {}
},
"organization": {
"id": 1,
"name": "acme corp",
"slug": "acme-corp",
"logo": null,
"short_logo": null,
"logo_dark": null,
"short_logo_dark": null,
"nrn": "organization=1",
"metadata": {}
}
},
"policy_details": null
}

Parameter

In a parameter approval, details.parameter matches the structure of a GET request to our parameter endpoint.

Payload example - Parameter
{
"approval_id": 1,
"approve_url": "https://api.nullplatform.com/approval/1/approve?token=xxx",
"deny_url": "https://api.nullplatform.com/approval/1/deny?token=yyy",
"requested_by": {
"user_id": 1,
"email": "alex.doe.developer@domain.com",
"first_name": "alex",
"last_name": "doe",
"avatar": null
},
"action": "parameter:read-secrets",
"details": {
"user": {
"id": 123,
"email": "alex.doe.developer@domain.com",
"status": "active",
"firstName": "alex",
"lastName": "doe",
"organizationId": 1,
"avatar": null,
"type": "person",
"provider": "cognito",
"nrn": "organization=1",
"metadata": {}
},
"parameter": {
"id": 11,
"name": "my secret",
"nrn": "organization=1:account=2:namespace=3:application=4",
"type": "environment",
"encoding": "plaintext",
"variable": "MY_SECRET",
"secret": true,
"values": [],
"version_id": 11,
"read_only": false
},
"application": {
"id": 4,
"name": "Acme parameters app",
"status": "active",
"namespace_id": 3,
"repository_url": "https://github.com/acme-corp/kong-namespace-acme-parameters-app",
"slug": "acme-parameters-app",
"template_id": 9,
"auto_deploy_on_creation": false,
"repository_app_path": null,
"is_mono_repo": false,
"tags": {},
"nrn": "organization=1:account=2:namespace=3:application=4",
"metadata": {}
},
"namespace": {
"id": 3,
"name": "Kong namespace",
"account_id": 2,
"slug": "kong-namespace",
"status": "active",
"nrn": "organization=1:account=2:namespace=3",
"metadata": {}
},
"account": {
"id": 2,
"name": "main",
"organization_id": 1,
"repository_prefix": "acme-corp",
"repository_provider": "github",
"status": "active",
"slug": "acme-corp-main",
"nrn": "organization=1:account=2",
"metadata": {}
},
"organization": {
"id": 1,
"name": "acme corp",
"slug": "acme-corp",
"logo": null,
"short_logo": null,
"logo_dark": null,
"short_logo_dark": null,
"nrn": "organization=1",
"metadata": {}
}
},
"policy_details": null,
"expires_at": "2025-02-17T20:30:35.563Z",
"time_to_reply": "259200000",
"allowed_time_to_execute": "86400000"
}

Services

This is the payload you receive when a service action is created. It matches the structure of a GET request to our service action spec endpoint.

Payload example - Service
{
"action": "service:action:create",
"id": "6f3d91ba-4e2c-41f8-9c0a-bb1e2d44a7fc",
"name": "create-testing",
"slug": "create-testing",
"status": "pending",
"created_at": "2025-03-18T14:09:33.412Z",
"updated_at": "2025-05-10T08:47:19.983Z",
"parameters": {
"fifo": false,
"dead_letter": false
},
"results": {},
"type": "create",
"specification": {
"id": "f4ce298b-9d7e-4564-8a12-7e0dcb11f5a6",
"slug": "create-sqs-queue"
},
"service": {
"id": "73bda6f0-2c91-4fa7-bf3a-dccf8c4e7e1d",
"slug": "testing",
"attributes": {
"visibility_timeout": 30
},
"specification": {
"id": "8c1a3f92-b7e0-4d13-a98f-21f56ae0c4bb",
"slug": "sqs-queue"
},
"dimensions": {}
},
"link": null,
"tags": {
"organization_id": "1",
"organization": "acme-corp",
"application_id": "4",
"application": "acme-services-action-app",
"account_id": "2",
"account": "main",
"namespace_id": "3",
"namespace": "Kong namespace"
},
"entity_nrn": "organization=1:account=2:namespace=3:application=4"
}

Audit

This is a payload example with entity context you receive when an audit event is created.

The message_id field is stable across retry attempts. If your endpoint fails to respond in time and nullplatform retries the delivery, all retries carry the same message_id. Use it to deduplicate events on the receiving end.

Payload example - audit
{
"entity_context":
{
"organization_id": 1,
"organization_name": "acme corp",
"organization_slug": "acme-corp",
"account_id": 2,
"account_name": "main",
"account_slug": "acme-corp-main",
"namespace_id": 3,
"namespace_name": "Kong namespace",
"namespace_slug": "kong-namespace",
"application_name": "Acme Test App",
"application_slug": "acme-test-app"
},
"user_email": "alex.doe.developer@domain.com",
"user_type": "person",
"entity_data":
{
"version": "12",
"id": 4,
"name": "Acme Test App",
"status": "active",
"namespace_id": 3,
"repository_url": "https://github.com/acme-corp/kong-namespace-acme-test-app",
"slug": "acme-test-app",
"template_id": 9,
"auto_deploy_on_creation": false,
"repository_app_path": null,
"is_mono_repo": false,
"tags":
{},
"nrn": "organization=1:account=2:namespace=3:application=4",
"metadata":
{}
},
"entity": "application",
"entity_id": "4",
"method": "PATCH",
"status": 204,
"url": "/application/4",
"ips": "",
"headers":
{
"connection": "close",
"host": "api.nullplatform.io",
"x_forwarded_for": "11.2.33.444, 22.3.44.555",
"x_real_ip": "22.3.44.555",
"content_length": "12",
"x_forwarded_proto": "https",
"x_forwarded_port": "443",
"x_amzn_trace_id": "Root=1-123bbccd-456a7b8901234cde5f67f890",
"accept": "application/json, text/plain, */*",
"content_type": "application/json",
"np_user_id": "123",
"np_organization_id": "1",
"authorization": "[REDACTED]",
"user_agent": "axios/1.1.1",
"accept_encoding": "gzip, compress, deflate, br",
"x_datadog_trace_id": "99",
"x_datadog_parent_id": "88",
"x_datadog_sampling_priority": "-1",
"x_datadog_tags": "_dd.p.tid=89f7cd21a1b2c3d4",
"traceparent": "00-89f7cd21a1b24e3a9f0b7c8d6e5a4c3b2d1",
"tracestate": "dd=t.tid:89f7cd21a1b2c3d4;t.dm:-3;s:-1;p:a4c3b2d1"

},
"request_body":
{
"name": "Acme Test App"
},
"organization_id": 1,
"user_id": 123,
"application": "acme-test-app",
"scope": "production-argentina",
"organization_name": "acme corp",
"organization_slug": "acme-corp",
"name": "Acme Test App",
"slug": "acme-test-app",
"date": "2025-05-18T08:47:19.984Z",
"messageId": "abc-7d2fe831-a3b9-495c-9f17-3a8a123bfc6c"
}

Entity

This is the payload you receive when an entity hook notification is sent. It includes a callback_url that your endpoint must respond to after processing the hook. See Entity hooks for the full setup guide.

Payload example - Entity (scope creation hook)
{
"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"
}
}
note

Entity hook notifications require a response to the callback_url. Your endpoint must send a POST request to approve or reject the operation. See Responding to a hook for details.

Parameters

This is the payload you receive when a parameter lifecycle event is triggered. The details object contains the parameter and its full resource hierarchy.

Payload example - Parameter store
{
"action": "parameter:store",
"details": {
"parameter": {
"id": 11,
"name": "database-connection-string",
"nrn": "organization=1:account=2:namespace=3:application=4",
"type": "environment",
"encoding": "plaintext",
"variable": "DATABASE_CONNECTION_STRING",
"secret": true,
"read_only": false
},
"application": {
"id": 4,
"name": "Acme Test App",
"status": "active",
"namespace_id": 3,
"slug": "acme-test-app",
"nrn": "organization=1:account=2:namespace=3:application=4"
},
"namespace": {
"id": 3,
"name": "Kong namespace",
"account_id": 2,
"slug": "kong-namespace",
"status": "active",
"nrn": "organization=1:account=2:namespace=3"
},
"account": {
"id": 2,
"name": "main",
"organization_id": 1,
"slug": "acme-corp-main",
"status": "active",
"nrn": "organization=1:account=2"
},
"organization": {
"id": 1,
"name": "acme corp",
"slug": "acme-corp",
"nrn": "organization=1"
}
}
}

Telemetry

This is the payload you receive when a telemetry event is triggered. Telemetry events carry provider-specific context in the arguments field and are typically consumed by agent channels configured for custom telemetry providers. See Telemetry for the full setup guide.

Payload example - Telemetry (metric data)
{
"action": "metric:data",
"arguments": {
"scope_provider": "f4ce298b-9d7e-4564-8a12-7e0dcb11f5a6",
"scope_id": "5",
"application_id": "4",
"namespace_id": "3",
"account_id": "2",
"organization_id": "1"
},
"tags": {
"organization_id": "1",
"organization": "acme-corp",
"application_id": "4",
"application": "acme-test-app",
"account_id": "2",
"account": "main",
"namespace_id": "3",
"namespace": "kong-namespace"
},
"entity_nrn": "organization=1:account=2:namespace=3:application=4:scope=5"
}
info

For alert source payloads, refer to the Notification Events API to inspect live event payloads using include_context=true.