Knowledge Base
Webhook Payloads
Webhook Payloads
When events occur that match your webhook subscription criteria, Narrative sends HTTP POST requests to your specified URL with JSON payloads containing detailed event information.
Payload Structure
All webhook payloads follow a consistent structure with event metadata and job-specific data.
Top-Level Fields
Field | Type | Description |
---|---|---|
id | string | Unique identifier for the webhook event |
type | string | Event type (e.g., "job.pending" , "job.running" ) |
created_at | string | ISO 8601 timestamp when the event was created |
data | object | Event-specific data containing detailed job information |
Job Data Object
The data
object contains comprehensive information about the job:
Field | Type | Description |
---|---|---|
job_id | string | Unique identifier for the job |
state | string | Current job state (pending , running , completed , failed ) |
type | string | Job type (materialize-view , forecast ) |
created_at | string | When the job was originally created |
updated_at | string | When the job was last updated |
dequeued_at | string | When the job started executing (null if not started) |
ended_at | string | When the job finished (null if still running) |
executor | string | Identifier of the executor handling the job |
data_plane_id | string | Data plane where the job is running and data is located |
idempotency_key | string | Key used to prevent duplicate job execution and resubmission |
input | object | Job input parameters including NQL query and dataset info |
request_source | object | Information about who/what initiated the job (user or automated process) |
result | object | Job results (null until completion), includes dataset statistics references |
Request Source Types
The request_source
object indicates who or what initiated the job:
API User Request:
"request_source": {
"company_id": 123,
"company_name": "Example Company",
"type": "api_user",
"user_id": 456,
"user_name": "John Doe"
}
Automated Process:
"request_source": {
"name": "materialized-view-refresh",
"type": "process"
}
Job Input Parameters
Common input parameters include:
Field | Description |
---|---|
first_run | true for the first execution of a dataset's job, false for subsequent runs |
create_as_view | true to create a Snowflake view instead of a table/materialized view |
dataset_id | ID of the dataset being processed |
dataset_name | Name of the dataset |
nql | NQL query being executed |
stats_enabled | Whether statistics collection is enabled |
Job Results
When a job completes successfully, the result
object contains:
Field | Description |
---|---|
dataset_id | ID of the dataset that was processed |
recalculation_id | Reference ID for dataset statistics calculation |
snapshot_id | Snapshot reference ID for dataset statistics |
Job Event Types by State
Different job types follow the same event structure but contain job-specific input parameters and results.
Job Pending (job.pending
)
Sent when a job is queued but hasn't started executing yet.
{
"created_at": "2025-01-21T14:25:12.687873Z",
"data": {
"created_at": "2025-01-21T14:25:12.687873Z",
"data_plane_id": null,
"dequeued_at": null,
"ended_at": null,
"executor": null,
"idempotency_key": "17ac7554-b572-4cff-8993-9916e0ebc808",
"input": {
"contains_delta_syntax": true,
"create_as_view": false,
"dataset_id": 12345,
"dataset_name": "example_dataset",
"first_run": true,
"merge": false,
"nql": "SELECT company_data.\"123\".\"age\", company_data.\"123\".\"app_id\" FROM company_data.\"123\"",
"partitions": null,
"stats_enabled": true
},
"job_id": "05703df0-7fbc-4706-9335-a6ba9f196783",
"request_source": {
"company_id": 123,
"company_name": "Example Company",
"type": "api_user",
"user_id": 456,
"user_name": "John Doe"
},
"result": null,
"state": "pending",
"type": "materialize-view",
"updated_at": "2025-01-21T14:25:12.687873Z"
},
"id": "dea7cecd-dacb-447d-b316-9e6b62e9864a",
"type": "job.pending"
}
Job Running (job.running
)
Sent when a job starts executing.
{
"created_at": "2025-01-21T14:30:07.652642Z",
"data": {
"created_at": "2025-01-21T14:25:12.687873Z",
"data_plane_id": null,
"dequeued_at": "2025-01-21T14:30:07.652642Z",
"ended_at": null,
"executor": "dedicated-job-76febf15-7fd4-4f75-a489-ece1e71d266e",
"idempotency_key": "17ac7554-b572-4cff-8993-9916e0ebc808",
"input": {
"contains_delta_syntax": true,
"create_as_view": false,
"dataset_id": 12345,
"dataset_name": "example_dataset",
"first_run": true,
"merge": false,
"nql": "SELECT company_data.\"123\".\"age\", company_data.\"123\".\"app_id\" FROM company_data.\"123\"",
"partitions": null,
"stats_enabled": true
},
"job_id": "05703df0-7fbc-4706-9335-a6ba9f196783",
"request_source": {
"company_id": 123,
"company_name": "Example Company",
"type": "api_user",
"user_id": 456,
"user_name": "John Doe"
},
"result": null,
"state": "running",
"type": "materialize-view",
"updated_at": "2025-01-21T14:30:07.646209Z"
},
"id": "77999717-e562-4210-b132-4ff7972e0736",
"type": "job.running"
}
Job Completed (job.completed
)
Sent when a job finishes successfully.
{
"created_at": "2025-01-21T14:37:36.802284Z",
"data": {
"created_at": "2025-01-21T14:25:12.687873Z",
"data_plane_id": null,
"dequeued_at": "2025-01-21T14:30:07.652642Z",
"ended_at": "2025-01-21T14:37:36.798417Z",
"executor": "dedicated-job-76febf15-7fd4-4f75-a489-ece1e71d266e",
"idempotency_key": "17ac7554-b572-4cff-8993-9916e0ebc808",
"input": {
"contains_delta_syntax": true,
"create_as_view": false,
"dataset_id": 12345,
"dataset_name": "example_dataset",
"first_run": true,
"merge": false,
"nql": "SELECT company_data.\"123\".\"age\", company_data.\"123\".\"app_id\" FROM company_data.\"123\"",
"partitions": null,
"stats_enabled": true
},
"job_id": "05703df0-7fbc-4706-9335-a6ba9f196783",
"request_source": {
"company_id": 123,
"company_name": "Example Company",
"type": "api_user",
"user_id": 456,
"user_name": "John Doe"
},
"result": {
"dataset_id": 12345,
"recalculation_id": "2ea589a5-b295-41b3-80b0-7d7a57e4fdbc",
"snapshot_id": 6361515361229277202
},
"state": "completed",
"type": "materialize-view",
"updated_at": "2025-01-21T14:37:36.798435Z"
},
"id": "a2f599d8-e53f-408a-a6de-4d094fbaf5aa",
"type": "job.completed"
}
Job Failed (job.failed
)
Sent when a job encounters an error.
{
"created_at": "2025-01-21T14:45:22.123456Z",
"data": {
"created_at": "2025-01-21T14:25:12.687873Z",
"data_plane_id": null,
"dequeued_at": "2025-01-21T14:30:07.652642Z",
"ended_at": "2025-01-21T14:45:22.118901Z",
"executor": "dedicated-job-76febf15-7fd4-4f75-a489-ece1e71d266e",
"idempotency_key": "17ac7554-b572-4cff-8993-9916e0ebc808",
"input": {
"contains_delta_syntax": true,
"create_as_view": false,
"dataset_id": 12345,
"dataset_name": "example_dataset",
"first_run": true,
"merge": false,
"nql": "SELECT company_data.\"123\".\"age\", company_data.\"123\".\"app_id\" FROM company_data.\"123\"",
"partitions": null,
"stats_enabled": true
},
"job_id": "05703df0-7fbc-4706-9335-a6ba9f196783",
"request_source": {
"company_id": 123,
"company_name": "Example Company",
"type": "api_user",
"user_id": 456,
"user_name": "John Doe"
},
"result": {
"error": "Query execution failed: Invalid column reference",
"error_code": "INVALID_COLUMN"
},
"state": "failed",
"type": "materialize-view",
"updated_at": "2025-01-21T14:45:22.118936Z"
},
"id": "f8e91d23-4567-890a-bcde-f123456789ab",
"type": "job.failed"
}
Next Steps
Creating Webhook Subscriptions
Now that you understand what webhooks will send you, learn how to create your first subscription.