Skip to main content

Webhook Integration

Team Enterpret avatar
Written by Team Enterpret
Updated over 2 weeks ago

Introduction

Enterpret's Custom Webhook integration lets you programmatically send customer feedback to Enterpret for analysis. This method is ideal for connecting feedback sources not supported by native integrations—making it easy to consolidate all your feedback in Enterpret.

When to Use a Custom Webhook

Use this integration when you're working with:

  • Review platforms that are not natively supported by Enterpret

  • Forum feedback that requires custom collection

  • Chatbot conversations from platforms without direct integrations

  • Survey tools specific to your industry

  • Internal feedback systems built for your organization

  • Feedback extracted from data warehouses (e.g., Redshift, BigQuery)

Note: Before proceeding, visit our native integrations page to see if your feedback source is already supported.

Prerequisites

  • API access to your feedback source

  • Engineering resources to implement the webhook connection

  • Enterpret account with administrator access

Not an engineer? This guide is designed for developers and contains technical instructions. Please share it with your engineering team for implementation.

Getting Started

Create an API Key

  1. Go to the Integrations page in your Enterpret instance

  2. Click +New Integration, and search for "Webhook"

  3. Choose the type of webhook integration based on your needs:

    • Feedback Integration – Send customer feedback into Enterpret

    • User Integration – Send user data to enrich feedback analysis

    • Account Integration – Sync account (company) data for account-level insights

  4. Provide a descriptive Display Name for your integration

    • This name will appear as the source for records throughout Enterpret

    • Add a detailed description to improve summary and prediction quality

  5. Once configured, you'll find your API key at the top of the integration page

    • This key should be included in all API requests to authenticate


Webhook Endpoint & Authentication

Endpoint URL: https://api.enterpret.com/webhook/custom/all

Authentication: Include your API key in every request header

api-key: your-api-key-here

Hard Limits (Enforced):

  • Maximum: 100 requests per minute (RPM)

  • Maximum payload size: 1MB per request

  • Recommended: Stay below 20 records per batch

Data Structure Overview

Webhook payloads must follow a structured JSON format. Enterpret accepts data in JSON format with a specific structure based on the feedback type.

Supported Feedback Types

We support four primary types of feedback:

  • REVIEW - Simple product/service reviews

  • CONVERSATION - Multi-message interactions between users and agents

  • SURVEY - Question-and-answer format feedback (NPS, CSAT, product feedback forms)

  • AUDIO_RECORDING - Voice recordings with optional transcripts

Core Fields

All records require these essential fields:

{
"records": [
{
"id": "unique-identifier",
"fileID": "source-identifier",
"type": "REVIEW",
"createdAt": 1768913221,
"metadata": {
"metadata": {
"custom_field": {
"array": {
"s": ["value1", "value2"]
}
}
}
}
}
]
}

Detailed Guides by Feedback Type

REVIEW Type

The simplest feedback format, ideal for app store reviews, product reviews, etc.

Required fields:

  • text: The content of the review

Example:

{
"type": "REVIEW",
"createdAt": 1716460800,
"text": "This product works exactly as described. Very happy with my purchase!",
"metadata": {
"rating": {
"array": {
"n": [5]
}
},
"platform": {
"array": {
"s": ["iOS App Store"]
}
}
}
}

SURVEY Type

Use for structured question-and-answer feedback like NPS, CSAT, and product feedback surveys.

Required fields:

  • surveyResponse: Contains an array of responses

  • Each response needs a question field

  • The answer and selectedOptions fields are optional

Example:

{
"records": [
{
"id": "survey-456",
"fileID": "nps-survey",
"type": "SURVEY",
"createdAt": 1768913221,
"surveyResponse": {
"responses": [
{
"question": "How likely are you to recommend our product to a colleague?",
"answer": [
"9"
]
},
{
"question": "What is the primary reason for your score?",
"answer": "The product is intuitive and saves me time on daily tasks."
},
{
"question": "Which features do you use most often?",
"selectedOptions": [
"Dashboard",
"Reports",
"API"
]
}
]
},
"metadata": {
"metadata": {
"nps_score": {
"array": {
"n": [
9
]
}
},
"user_segment": {
"array": {
"s": [
"Enterprise"
]
}
}
}
}
}
]
}

CONVERSATION Type

Ideal for support tickets, chat transcripts, or any back-and-forth communication.

Required fields:

  • conversation: Contains an array of messages

  • Each message needs text and actor fields

  • Actor must be one of: "user", "agent", or "bot"

Example:

{
"records": [
{
"id": "01JY05BQ6EV1RPSXJ61K0BV0YA",
"type": "CONVERSATION",
"fileID": "proto_chat",
"createdAt": 1768913221,
"conversation": {
"msgs": [
{
"actor": "bot",
"text": "Hello boom504!"
},
{
"actor": "bot",
"text": "Hello boom504!"
}
]
},
"metadata": {
"metadata": {
"src_account_id": {
"array": {
"s": [
"TybFPBMTLnY96T5nQ"
]
}
},
"website": {
"array": {
"s": [
"SportsBet"
]
}
},
"primary_product": {
"array": {
"s": [
"Cross Sell"
]
}
},
"tech": {
"array": {
"s": [
"Web"
]
}
},
"channel": {
"array": {
"s": [
"Desktop"
]
}
},
"value_segment": {
"array": {
"s": [
"High Value 1"
]
}
},
"active_segment": {
"array": {
"s": [
"Active High"
]
}
},
"sportsbook_ccf": {
"array": {
"s": [
"CCF 0.1"
]
}
},
"vip": {
"array": {
"s": [
"1"
]
}
},
"scrubbed": {
"array": {
"s": [
"0"
]
}
},
"first_deposit_date": {
"array": {
"s": [
"2022-11-13T00:00:00.000Z"
]
}
},
"last_active_date": {
"array": {
"s": [
"2025-06-18T00:00:00.000Z"
]
}
},
"bot_id": {
"array": {
"s": [
"01J0685Q1AYVRTHSKRSA289MKC"
]
}
},
"bot_name": {
"array": {
"s": [
"Sportsbet.io"
]
}
},
"language": {
"array": {
"s": [
"English"
]
}
}
}
}
}
]
}

AUDIO_RECORDING Type

Use for voice recordings from call centers, sales calls, or other audio feedback.

Required fields:

  • audioRecording: Contains the audioURL field

  • audioURL should be publicly accessible or have a long-lived signed URL

Supported formats: mp3, mp4, wav, flac, ogg, amr, webm, m4a

Optional: Include a transcript to improve analysis or use your own transcription

With Automatic Transcription:

{
"records": [
{
"id": "call-abc123",
"fileID": "sales-calls",
"type": "AUDIO_RECORDING",
"createdAt": 1768913221,
"audioRecording": {
"audioURL": "https://storage.example.com/calls/customer-feedback-call.mp3"
},
"metadata": {
"metadata": {
"call_duration_seconds": {
"array": {
"n": [
352
]
}
},
"call_type": {
"array": {
"s": [
"Sales Demo"
]
}
}
}
}
}
]
}

With Provided Transcript:

{
"records": [
{
"id": "call-xyz789",
"fileID": "support-calls",
"type": "AUDIO_RECORDING",
"createdAt": 1768913221,
"audioRecording": {
"audioURL": "https://storage.example.com/calls/support-call.mp3",
"transcript": {
"conversation": {
"units": [
{
"actor": "agent",
"actorID": "support-rep-42",
"text": "Thank you for calling customer support. How can I help you today?",
"metadata": {
"startTime": 1000,
"endTime": 5000
}
},
{
"actor": "user",
"actorID": "caller",
"text": "Hi, I'm having an issue with logging into my account.",
"metadata": {
"startTime": 5500,
"endTime": 9000
}
}
]
}
}
},
"metadata": {
"metadata": {
"issue_category": {
"array": {
"s": [
"Authentication"
]
}
}
}
}
}
]
}

Working with Metadata

Metadata provides crucial context about your feedback. Enterpret uses this data for filtering, analysis, and visualization.

Metadata Structure

All metadata follows this format:

{
"metadata": {
"metadata": {
"field_name": {
"array": {
"type_indicator": [
"value1",
"value2"
]
}
}
}
}
}
Supported Metadata Types

Strings: Use "s" as the type indicator for strings

"user_tier": { "array": { "s": ["Premium"] } }

Numbers: Use "n" as the type indicator for number [int, float]

"rating": { "array": { "n": [4.5] } }

Booleans: Use "b" as the type indicator for bool

"is_paying_customer": { "array": { "b": [true] } }

Multiple Values: Arrays can contain multiple values

"tags": { "array": { "s": ["bug", "ui", "mobile"] } }

Important: Each metadata field can only use one type. Mixing types (e.g., strings and numbers) in the same field is not supported. If you send a single values we will treat it as a single value like a key-value pair.

Data Mutability & Updating Records

What is Data Mutability?

Data mutability defines how Enterpret handles incoming records that share the same id.

When enabled
Sending a record with an existing id will update the original record instead of creating a duplicate. This is useful when you need to:

  • Update feedback content (for example, when a user edits a review in the source system)

  • Add or enrich metadata over time

  • Correct mistakes in previously ingested records

When disabled (default)
Records with duplicate ids are automatically skipped to prevent duplication. This is ideal for one-time or historical data imports where records should remain immutable.

How to Check if Data Mutability Is Enabled

Data mutability is configured per integration and must be enabled by Enterpret support.

To check whether it’s enabled for your integration:

  1. Contact your Customer Success Manager (CSM) or Enterpret Support

  2. Share your integration name or API key

  3. The team will confirm your current data mutability setting

Note: Data mutability is disabled by default for new webhook integrations and must be explicitly enabled.

How to Update Existing Records

Once data mutability is enabled, you can update a record by sending the same id with the updated fields.

Example: Updating a Review

{
"records": [
{
"id": "review-123",
"fileID": "appstore-reviews",
"type": "REVIEW",
"createdAt": 1768913221,
"text": "Updated review text after customer edited their review",
"metadata": {
"metadata": {
"rating": { "array": { "n": [5] } },
"updated_at": { "array": { "n": [1716500000] } }
}
}
}
]
}

Example: Adding Metadata to an Existing Record

{
"records": [
{
"id": "review-123",
"fileID": "appstore-reviews",
"type": "REVIEW",
"createdAt": 1716460800,
"text": "Original review text",
"metadata": {
"metadata": {
"rating": { "array": { "n": [5] } },
"user_tier": { "array": { "s": ["Premium"] } },
"lifetime_value": { "array": { "n": [50000] } }
}
}
}
]
}

Important Considerations

ID Consistency: Always use the same `id` format when updating records. The ID must match exactly (case-sensitive) because it's used to generate a deterministic UUID for record identification.

Metadata Updates: When updating metadata, the entire metadata attribute is replaced, not merged. If you want to add a new metadata field while keeping existing ones, you must include all existing metadata fields in your update request along with the new field.

Error Handling

Our API provides detailed error messages to help you troubleshoot issues with your webhook implementation.

Error Response Structure

When you encounter an error, you'll receive a JSON response with:

Field

Type

Description

msg

String

A detailed error message explaining the issue

code

String

An error code identifier

referenceID

String

A unique ID to reference when contacting support

Common Error Responses

Error Code

HTTP Status

Is Retriable?

Description

ErrCodeInternalError

500

Yes

Server-side issue - retry with exponential backoff

ErrCodeInvalidRequestArgument

400

No

Issue with request format or data

ErrCodeMissingRequiredField

400

No

Required field is missing from the payload

ErrCodeInvalidFieldFormat

400

No

Field format doesn't match expected schema

ErrCodeExceededBatchLimit

400

No

Too many records in single request (max 20)

ErrCodePayloadTooLarge

413

No

Request payload exceeds 1MB limit

ErrCodeRateLimitExceeded

429

Yes

Too many requests - implement backoff

ErrCodeInvalidAPIKey

401

No

API key is invalid or missing

Example Error Response

{
"msg": "Missing required field: 'id'. Each record must have a unique identifier.",
"code": "ErrCodeMissingRequiredField",
"referenceID": "8B5OQA"
}

Troubleshooting Tips

Authentication Issues: Verify your API key is correct and the integration is enabled

Format Problems: Ensure your JSON is valid and follows the required schema

Missing Fields: Check that all required fields are present for your feedback type

Invalid Values: Verify field values meet the requirements (e.g., actor types)

Large Payloads: Consider breaking very large requests into smaller batches

Implementation Examples

Example: Sending a Batch of Reviews

import requests
import json
import time

# Configuration
api_key = "your-api-key"
endpoint = "https://api.enterpret.com/webhook/custom/all"

# Sample data: creating 3 sample reviews
reviews = [
{
"id": f"review-{i}",
"fileID": "product-reviews",
"type": "REVIEW",
"createdAt": int(time.time()),
"text": f"Sample review text {i}",
"metadata": {
"metadata": {
"rating": {
"array": {
"n": [4]
}
}
}
}
}
for i in range(1, 4)
]

# Prepare payload
payload = {
"records": reviews
}

# Send request
headers = {
"api-key": api_key,
"Content-Type": "application/json"
}

response = requests.post(
endpoint,
headers=headers,
data=json.dumps(payload)
)

# Handle response
if response.status_code == 200:
print("Successfully sent reviews to Enterpret")
else:
print(f"Error: {response.status_code}")
print(response.text)
Example: Extracting Data from Your Database

Example: Extracting Data From our Database

import requests
import json
import psycopg2
import time

# Database connection
conn = psycopg2.connect(
"dbname=feedback user=user password=pass host=localhost"
)
cur = conn.cursor()

# Fetch data
cur.execute(
"SELECT id, created_at, feedback_text, rating "
"FROM customer_feedback "
"LIMIT 100"
)
rows = cur.fetchall()

# Prepare records
records = []

for row in rows:
db_id, created_at, feedback_text, rating = row

# Convert datetime to Unix timestamp
timestamp = int(created_at.timestamp())

record = {
"id": f"db-{db_id}",
"fileID": "database-extract",
"type": "REVIEW",
"createdAt": timestamp,
"text": feedback_text,
"metadata": {
"metadata": {
"rating": {
"array": {
"n": [rating]
}
},
"source": {
"array": {
"s": ["internal_database"]
}
}
}
}
}

records.append(record)

# Send to Enterpret
headers = {
"api-key": "your-api-key",
"Content-Type": "application/json"
}

payload = {
"records": records
}

response = requests.post(
"https://api.enterpret.com/webhook/custom/all",
headers=headers,
data=json.dumps(payload)
)

print(f"Status: {response.status_code}")
print(response.text)

# Close database connection
cur.close()
conn.close()

Interactive Code Examples

We provide downloadable notebooks with executable code examples to accelerate your integration development:

Best for: Initial testing, debugging, and non-Python environments

This notebook contains command-line examples that work in any environment. Use it when you need to:

  • Test the API immediately without writing code

  • Debug integration issues quickly

  • Work in non-Python development environments

  • Validate your API key and endpoint connectivity

What's included:

  • Working cURL commands for all feedback types

  • Error handling examples

  • Authentication testing

  • Quick validation scripts

Download cURL Examples Notebook:

Python Implementation Script

Best for: Production integrations and Python development teams

This script provides production-ready Python classes with type hints for building robust webhook integrations. Use it when you need:

  • Structured, maintainable code for your integration

  • Type safety and IDE support

  • Reusable classes for different feedback types

  • A foundation for scaling your webhook implementation

What's included:

  • Complete Python class definitions

  • Type-safe implementations

  • Error handling and retry logic

Download Python Implementation Script and Sample Payload:

python3 Script_for_sending_records_to_enterpret.py --payload sample_payload.json  

Best Practices

Data Placement Guide: Feedback Content vs Metadata

Place data in the correct fields so Enterpret can analyze feedback and use metadata for filtering and context.

Feedback content fields (what customers said)

Use these for the actual customer feedback text:

  • text (REVIEW type) — the review text

  • conversation.msgs[].text (CONVERSATION type) — message content

  • surveyResponse.responses[].answer (SURVEY type) — open-ended answers

  • surveyResponse.responses[].selectedOptions (SURVEY type) — selected options

Metadata fields (context about the feedback)

Use metadata for structured, contextual information:

  • Ratings, scores (NPS, CSAT, star ratings)

  • Demographics (country, region, language)

  • Customer attributes (tier, segment, account ID)

  • Transactional data (order ID, product ID, ticket ID)

  • Timestamps and statuses

  • Platform/device information

Data Quality

  • Include rich metadata - The more context you provide, the better Enterpret can analyze your feedback

  • Maintain consistent IDs - Use stable, unique identifiers for your records

  • Provide accurate timestamps - This helps with trend analysis over time

  • Handle special characters properly in your JSON strings

  • Set appropriate fileType values to organize your feedback sources

  • Right position for feedback vs metadta: Please keep the information like customer rating, nps score, country etc in the metadta and customer text feedback in the actual Conversati like text in review, survery wquestion ans.

Performance

  • Batch requests: Send multiple records per request instead of one at a time (up to 20 records per batch).

  • Retry on transient failures: Implement retry logic for 5xx errors using exponential backoff.

  • Use compression: Enable request compression for larger payloads when possible.

  • Schedule regular syncs: Run periodic syncs to keep your data up to date in Enterpret.

  • Delay between two request: To avoid failure please keep 1-2 sec gap between the consecutive requests.

Security

  • Protect your API key - Treat it like a password

  • Use HTTPS for all requests to ensure encryption

  • Audit data before sending to ensure no sensitive information is included

  • Consider IP restrictions for your API access if available

Getting Help

If you encounter any issues implementing your webhook integration:

  • Check error messages for specific guidance on what needs to be fixed

  • Review this documentation to ensure your implementation follows the requirements

  • Contact Enterpret Support with your referenceID if you need additional assistance

Support Channels:

  • Help Center: helpcenter.enterpret.com

  • Dashboard: Use the chat widget in your dashboard


Did this answer your question?