Skip to main content

Webhooks

Webhooks enable real-time communication between Gen8 and your external systems. You can receive notifications about chat events, trigger chats programmatically, and build sophisticated integrations that respond to AI-generated content.

Understanding Webhooks

A webhook is an HTTP callback—when something happens in Gen8, it sends data to a URL you specify. This lets your systems react immediately to events like message generation, status changes, or errors without constantly polling for updates.

Gen8 supports webhooks in two main ways:

  1. Outbound webhooks: Gen8 notifies your systems when events occur
  2. Chat initiation via API: Start conversations programmatically and receive results via webhook

Configuring Webhooks

Template-Level Webhooks

You can configure webhooks directly in your agent template:

  1. Open the template editor
  2. Find the webhook configuration section
  3. Enter your webhook URL
  4. Select the HTTP method (POST, PUT, DELETE, or PATCH)
  5. Add any required headers (like authentication tokens)
  6. Choose which events should trigger notifications

This webhook fires for all chats using this template.

Per-Chat Webhooks

You can also specify webhooks when starting a chat via API, even if the template doesn't have one configured. This allows dynamic routing based on context or user-specific callback URLs.

Event Types

Gen8 can notify you about various events throughout a conversation's lifecycle. When configuring a webhook, specify which event types you want to receive.

Common Payload Structure

All standard webhook events share a common JSON structure. The data field varies by event type.

{
"metadata": {
"userId": "user_123",
"organizationId": "org_xyz",
"templateId": "template_abc",
"chatId": "chat_456",
"messageNumber": 2,
"externalId": "your-reference-id",
"publicTokenId": "token_if_applicable"
},
"type": "string", // The specific event type (e.g., "STATUS_CHANGE", "RESULT")
"timestamp": 1734628377000,
"status": "string", // Current chat status
"data": { ... } // Event-specific data
}

RESULT (Completed)

Triggered when a message is fully generated. This is the most critical event for capturing AI responses.

Trigger: When the AI generation has successfully finished. Chat Status: completed

{
"type": "result",
"chatId": "chat_abc123",
"status": "completed",
"data": {
"response": "Here is the generated response content..."
}
}

STATUS_CHANGE

Receive updates as the chat moves through different states. Useful for showing progress indicators or tracking conversation flow.

Possible status values:

  • initiated — Chat created, not yet processing
  • processing — Processing user input (before file loading)
  • generating — AI is generating a response (files loaded)
  • completed — Response generation finished
  • waiting_for_input — Awaiting user input (for multi-turn forms)
  • failed — An error occurred

Payload Example (Processing):

{
"type": "status",
"status": "processing",
"data": {
"inputs": {}
}
}

USER_MESSAGE

Triggered when a user adds a message to the conversation.

Trigger: Immediately after chat initiation (with initial inputs) or when a user sends a message.

{
"type": "user_message",
"status": "undefined",
"data": {
"message": "User's message content",
"role": "user",
"attachments": [
{ "fileId": "f1", "fileName": "doc.pdf" }
]
}
}

ERROR

Get notified when something goes wrong.

{
"type": "error",
"status": "failed",
"data": {
"error": {
"code": "INTERNAL_ERROR",
"message": "Failed to generate response",
"recoverable": false
}
}
}

AGENT_MESSAGE

Triggered when the AI assistant adds a message. May include requested input if the agent is asking for more information.

{
"type": "agent_message",
"data": {
"message": "I'd be happy to help...",
"role": "assistant",
"requestedInput": {
"template": [
{ "type": "textfield", "label": "Order Number", "required": true }
]
}
}
}

ALL

Subscribe to every event type. Useful during development or when you need complete visibility into conversation activity.

Starting Chats via API

You can initiate conversations programmatically and receive results through webhooks. This requires a public token that grants access to the template.

API Endpoint

POST https://your-gen8-instance.com/startChatWebhook

Request Format

{
"templateId": "template_abc123",
"organizationId": "org_xyz",
"token": "your-public-token",
"inputValues": ["value for first input", "value for second input"],
"publicTokenId": "pubTok_optional",
"externalId": "your-own-reference-id",
"onCompleteWebhook": {
"url": "https://your-system.com/webhook/callback",
"method": "POST",
"headers": {
"Authorization": "Bearer your-auth-token",
"X-Custom-Header": "custom-value"
},
"eventTypes": ["RESULT", "ERROR"]
}
}
FieldRequiredDescription
templateIdYesThe ID of the template/agent to use
organizationIdYesYour organization ID
tokenYesA public token that has access to this template (see Public Sharing)
inputValuesYesArray of values for the template's form inputs, in order
publicTokenIdNoSpecific public token ID if tracking multiple tokens
externalIdNoYour own reference ID to correlate with your systems
onCompleteWebhookNoWebhook configuration for receiving results

Response

{
"success": true,
"chatId": "chat_generated123"
}

The chatId lets you track this specific conversation. Results arrive at your webhook URL as the conversation progresses.

Handling Webhook Requests

Your webhook endpoint should:

  1. Respond quickly — Return a 200 status within a few seconds. Do heavy processing asynchronously.
  2. Validate the request — Check authentication headers you configured
  3. Handle duplicates — Webhooks may occasionally retry; use idempotent operations
  4. Log failures — Track any processing errors for debugging

Example Handler (Node.js/Express)

app.post('/webhook/gen8', (req, res) => {
const { type, chatId, metadata } = req.body;

// Validate authentication if you added headers
const authHeader = req.headers['authorization'];
if (authHeader !== 'Bearer your-expected-token') {
return res.status(401).send('Unauthorized');
}

// Process based on event type
switch (type) {
case 'result':
handleCompletedMessage(chatId, req.body.response);
break;
case 'error':
handleError(chatId, req.body.error);
break;
case 'status':
updateChatStatus(chatId, req.body.status);
break;
}

// Respond immediately
res.status(200).send({ received: true });
});

Webhook-Only Chat Type

For fully automated workflows, you can create agents with the "Webhook-only" chat type. These agents:

  • Don't display a user interface
  • Are triggered entirely via API
  • Process inputs and return results through webhooks
  • Are ideal for background automation and system integrations

This is perfect for scenarios like:

  • Processing form submissions from your website
  • Handling scheduled report generation
  • Automating responses to external events
  • Building AI-powered APIs

How it Works

  1. Trigger: When generateInitialResponse is called for a chat with type: "webhook-only".
  2. Mechanism: The system gathers all inputs, resolves the template, downloads file attachments, and then makes a single POST request to the configured webhook URL.
  3. Payload:
    {
    "inputs": { ... }, // Parsed input values
    "resolvedTemplate": "string", // The prompt template with snippets resolved
    "responseWebhookUrl": "string", // URL for the external system to post the reply back to
    "attachments": ["url1", "url2"], // Download URLs for files
    "txtFiles": ["content1", "content2"] // Text content of text-based files
    }
  4. Expected Behavior: The external system receives this payload, processes it, and then sends a POST request to the responseWebhookUrl with the response content.

Sending Responses to Webhook Chats

For webhook-only chats or chats waiting for external input, you can send responses programmatically:

POST https://your-gen8-instance.com/publishExternalMessageToChat/{chatId}/{responseWebhookToken}
{
"content": "Your external system's response content"
}

This allows external systems to participate in the conversation flow.

Security Best Practices

When implementing webhooks:

Authenticate requests — Always include authentication tokens in your webhook configuration and validate them in your handler. This prevents unauthorized systems from sending fake events.

Use HTTPS — All webhook URLs should use HTTPS to encrypt data in transit.

Validate payloads — Check that incoming data matches expected formats before processing.

Keep secrets secure — Don't expose API tokens or sensitive information in webhook URLs. Use headers for authentication instead.

Implement rate limiting — Protect your webhook endpoints from abuse with appropriate rate limits.

Set reasonable timeouts — Respond to webhook requests promptly. Gen8 may retry if your endpoint takes too long.

Troubleshooting

Webhook Not Receiving Events

  • Verify the URL is publicly accessible (not localhost or behind a firewall)
  • Check that your server is running and the endpoint exists
  • Confirm the correct event types are selected
  • Look for any network or DNS issues

Authentication Failures

  • Double-check header names and values match exactly
  • Ensure tokens haven't expired
  • Verify your handler checks the right headers

Missing Events

  • Confirm you've subscribed to the event types you need
  • Check if STATUS_CHANGE is included if you need status updates
  • Verify the webhook is configured at the template or chat level

Timeouts

  • Ensure your webhook responds within 30 seconds
  • Move heavy processing to background jobs
  • Return 200 immediately, then process asynchronously

Payload Parsing Errors

  • Check your JSON parsing handles all field types
  • Handle optional fields that may be null or missing
  • Log raw payloads during development for debugging