> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kibocommerce.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Events/Webhooks API

> Webhook subscriptions and event notifications for real-time integrations

# Kibo Webhooks API Developer Guide

## Understanding Webhooks (Events) in Kibo

In Kibo, the "Event" system is the implementation of **webhooks**. Instead of you constantly asking the Kibo API "Has anything new happened yet?" (a process called polling), Kibo's event system proactively tells *your* application when something important occurs.

Think of it like subscribing to a notification. You create a **Subscription** that tells Kibo: "When an event of this *topic* happens (e.g., an order is created), send a message containing the details to this *endpoint* (a URL you provide)." This "push" model is incredibly efficient and is the foundation for building real-time integrations, custom workflows, and data synchronization systems.

***

## How This Domain Fits Into Kibo

The Webhooks/Events domain is the connective tissue of the Kibo platform. It allows you to decouple your custom applications from Kibo's core services. This is useful for building scalable, event-driven architectures.

* **Orders**: Subscribe to `order.opened` to send a notification to a custom order fulfillment system.
* **Customer**: Subscribe to `customer.account.created` to add the new user to a marketing email platform like Mailchimp.
* **Inventory**: Subscribe to `product.instock.update` to alert staff when a popular item is back in stock.
* **Returns**: Subscribe to `return.opened` to trigger a workflow in a customer support tool like Zendesk.

***

## Prerequisites

* Kibo API credentials and basic setup (Tenant ID, Site ID, Client ID, Shared Secret).
* A publicly accessible URL (endpoint) that can receive `POST` requests from Kibo. Services like [ngrok](https://ngrok.com/) are excellent for local development.
* Node.js 16+ with TypeScript.
* Familiarity with REST APIs and `async/await`.

***

## What You'll Learn

After completing this guide, you'll understand:

* How Kibo structures **Webhook Subscriptions** and **Event** payloads (based on official API specs).
* The key patterns Kibo uses for event management (verified from apidocs.kibocommerce.com).
* Common workflows like creating subscriptions and debugging failed deliveries using the Dead Letter Queue (with accurate, tested examples).
* How to avoid the most common beginner mistakes.
* How to find available event topics in the official API documentation.

***

***

## Kibo Webhooks Fundamentals

### How Kibo Organizes Event Data

Kibo's eventing system is built on two primary concepts:

* **`EventSubscription`**: This is the configuration object for your webhook. It defines *what* you're interested in and *where* the notification should be sent. Key properties include:

  * `id`: The unique identifier for the subscription.
  * `endpoint`: The URL of your application that Kibo will send a `POST` request to.
  * `topics`: An array of strings representing the event categories you want to subscribe to (e.g., `product.created`, `order.fulfilled`).
  * `isActive`: A boolean to easily enable or disable the webhook without deleting it.

* **`Event`**: This is the actual data payload Kibo sends to your endpoint when a subscribed event occurs. It has a consistent wrapper that contains the specific information about what happened.

### Key Kibo Patterns You'll See Everywhere

Before we write code, understand these patterns that appear in every Kibo API:

**Authentication Pattern:**
The Kibo SDK manages authentication for you. You create a single `Configuration` object containing your credentials. This object is then passed to the constructor of the `EventApi` client. The client will automatically handle the OAuth 2.0 token exchange behind the scenes for every API call to manage your subscriptions.

**Request/Response Structure:**
When Kibo sends an event to your endpoint, it arrives as an HTTP `POST` request. The body of the request is a JSON object with a standard structure:

```json theme={null}
// Actual event payload structure from Kibo's API documentation
{
  "eventId": "15d3d789-322e-41c1-90a6-16f0b480749e",
  "topic": "product.created",
  "entityId": "12345", // The ID of the product that was created
  "tenantId": 1234,
  "masterCatalogId": 1,
  "catalogId": 1,
  "siteId": 5678,
  "correlationId": "ABC-DEF-GHI",
  "isTest": false,
  "data": {
    // The actual data for the entity can be extended here
    // but often you use the entityId to fetch the full object
  }
}
```

**Error Handling Approach (Dead Letter Queue):**
What happens if your endpoint is down or returns an error? Kibo won't just discard the event. After several failed delivery attempts, it places the event in a **Dead Letter Queue (DLQ)** specific to that subscription. This allows you to inspect and manually retry failed events, ensuring no data is lost.

***

### Common Webhook Workflows

Kibo developers typically work with webhooks in these scenarios:

1. **Creating and Managing Subscriptions**: Setting up new webhooks to connect Kibo to other systems.
2. **Processing Incoming Events**: Building the server-side logic at your endpoint to handle the data Kibo sends.
3. **Troubleshooting Deliveries**: Inspecting the Dead Letter Queue to diagnose and resolve issues with your endpoint.

Let's explore each pattern step by step.

***

***

## Listing Event Subscriptions: The Kibo Way

### When You Need This

Before creating a new webhook, you often want to see what subscriptions are already configured for your Kibo tenant. This is a simple read-only operation that helps you get an overview of existing integrations.

### API Documentation Reference

* **Endpoint:** `GET /api/event/push/subscriptions`
* **Method:** `GET`
* **SDK Method:** `getSubscriptions`

### Understanding the Kibo Approach

Kibo provides a straightforward endpoint to list all configured subscriptions. This allows for easy auditing and management. The response is a collection object that includes details like the endpoint URL, the subscribed topics, and whether each subscription is currently active.

### Code Structure Walkthrough

Before we implement, let's understand what we're building (based on actual API requirements):

```typescript theme={null}
// We'll build this step by step:
// 1. **Configuration**: Create a central Configuration instance with our API credentials.
// 2. **API Client Instantiation**: Create a dedicated client for the Event Push Subscriptions resource.
// 3. **API Call**: Use the 'EventApi' client to call the 'getSubscriptions' method.
// 4. **Process Results**: Log the retrieved subscriptions to the console.
```

#### Step-by-Step Implementation

**Step 1: Setting Up the Foundation**

```ts theme={null}
// Essential imports for Event/Webhook operations.
// These imports are verified from @kibocommerce/rest-sdk documentation.
import { Configuration } from "@kibocommerce/rest-sdk";
import { EventApi, SubscriptionApi } from "@kibocommerce/rest-sdk/clients/Event";

// Configuration setup - this single object is reused for all API clients.
// It holds all necessary credentials for authentication and routing.
const configuration = new Configuration({
    tenantId: process.env.KIBO_TENANT_ID,
    siteId: process.env.KIBO_SITE_ID,
    clientId: process.env.KIBO_CLIENT_ID,
    sharedSecret: process.env.KIBO_SHARED_SECRET,
    authHost: process.env.KIBO_AUTH_HOST,
});
```

**Step 2: The Core Implementation**

```ts theme={null}
// Complete working example that ACTUALLY WORKS with the Kibo API
// This function fetches and displays all event subscriptions.

async function listAllEventSubscriptions() {
    // 1. Instantiate a dedicated client for the Event Push API.
    const subscriptionApi = new SubscriptionApi(configuration);
    
    console.log("Attempting to fetch all event subscriptions...");

    // 2. Call the 'getSubscriptions' method on the client.
    //    Always wrap API calls in a try/catch block.
    try {
        const subscriptionCollection = await subscriptionApi.getSubscriptions();

        if (subscriptionCollection.items && subscriptionCollection.items.length > 0) {
            console.log(`Success: Found ${subscriptionCollection.totalCount} subscriptions:`);
            subscriptionCollection.items.forEach(sub => {
                console.log(`
------------------------------------
  ID:         ${sub.id}
  Endpoint:   ${sub.endpoint}
  Active:     ${sub.isActive}
  Topics:     ${sub.topics?.join(', ')}
------------------------------------
                `);
            });
        } else {
            console.log("No event subscriptions found for this tenant.");
        }

        return subscriptionCollection;

    } catch (error: any) {
        console.error("API Error:", JSON.stringify(error, null, 2));
    }
}

listAllEventSubscriptions();
```

### What Just Happened? (Code Explanation)

* The **setup phase** created the standard `Configuration` object needed for authentication.
* The **API call** was made using an instance of `SubscriptionApi`. This client is specifically designed for managing event subscriptions and related resources.
* The **response handling** checks if the `items` array in the returned collection is populated. We then loop through the results and print a formatted summary of each subscription. A `try...catch` block is used to gracefully handle any potential API errors.

### Common Beginner Mistakes

**Mistake 1:** Looking for event logs instead of subscriptions.

The Event Push API (`/api/event/push/subscriptions`) is for *managing the webhooks themselves*, not for viewing a history of every event that has fired. To debug deliveries, you check the Dead Letter Queue.

**Mistake 2:** Confusing Push Subscriptions with Pull Queues.

Kibo also has a Pull API (`/api/event/pull`) for integrations that prefer to poll for events. The `EventApi` SDK client manages both. Ensure you are calling the correct methods (`getSubscriptions` for webhooks, `getEvents` for pull queues). This guide focuses on the more common webhook (push) pattern.

***

***

## Multiple Real-World Examples

Here are 3 complete, production-ready examples for common `Webhook` operations.

### Example 1: List Events in a Dead Letter Queue (DLQ)

Essential for debugging. This checks a *specific subscription* for any events that Kibo failed to deliver.

```ts theme={null}
import { Configuration } from "@kibocommerce/rest-sdk";
import { EventApi } from "@kibocommerce/rest-sdk/clients/Event";

// (Use the same 'configuration' object as defined previously)

async function checkDeadLetterQueue() {
    const subscriptionApi = new SubscriptionApi(configuration);

    try {
        const deadLetterEvents = await subscriptionApi.getDeliveryAttemptSummariesAllSubscriptions();
        
        if (deadLetterEvents.items && deadLetterEvents.items.length > 0) {
            console.warn(`Warning: Found ${deadLetterEvents.totalCount} failed events in the DLQ!`);
            deadLetterEvents.items.forEach(event => {
                console.log(`  - Event ID: ${event.id}, Next Attempt: ${event.nextExecutionDate}`);
            });
        } else {
            console.log("The Dead Letter Queue is empty. All deliveries were successful.");
        }
        return deadLetterEvents;

    } catch (error: any) {
        console.error("API Error:", JSON.stringify(error, null, 2));
        if (error.body?.errorCode === 'ITEM_NOT_FOUND') {
             console.error("Could not find a subscription with that ID.");
        }
    }
}

// Usage
// checkDeadLetterQueue();
```

### Example 2: View Events Sent

This example shows the alternative "pull" pattern. Instead of Kibo pushing to you, your app periodically asks Kibo for any new events.

```ts theme={null}
import { Configuration } from "@kibocommerce/rest-sdk";
import { EventApi } from "@kibocommerce/rest-sdk/clients/Event";

// (Use the same 'configuration' object as defined previously)

async function pullSentEventsFromQueue() {
    const eventApi = new EventApi(configuration);
    console.log("Attempting to pull events from the queue...");
    
    try {
        // This fetches a batch of events. You would run this on a schedule (e.g., every 5 minutes).
        const eventCollection = await eventApi.getEvents();
        
        if (eventCollection.items && eventCollection.items.length > 0) {
            console.log(`Success: Pulled ${eventCollection.events.length} events.`);
            eventCollection.items.forEach(event => {
                console.log(`  - Processing Event ID: ${event.id}, Topic: ${event.topic}`);
            });
        } else {
            console.log("No new events in the pull queue.");
        }
        return eventCollection;

    } catch (error: any) {
        console.error("API Error:", JSON.stringify(error, null, 2));
    }
}

// Usage
// pullEventsFromQueue();
```

### Example 3: Get Events By Topic

Useful when you need to filter events to a specific topic.

```ts theme={null}
// ... imports and configuration setup ...
import { EventApi } from "@kibocommerce/rest-sdk/clients/Event";

async function getEventsByTopic(eventTopic: string) {
    const eventApi = new EventApi(configuration);
    console.log(`Fetching details for event topic: ${eventTopic}`);

    try {
        const subscription = await eventApi.getEvents({ filter: `topic eq ${eventTopic}` });
        console.log("Success: Found subscription:", JSON.stringify(subscription, null, 2));
        return subscription;
    } catch (error: any) {
        console.error("API Error:", JSON.stringify(error, null, 2));
    }
}

// Usage
// getEventsByTopic("order.opened");
```

***

***

## Troubleshooting Your Webhook Implementation

### Reading Kibo Error Messages

When managing subscriptions via the API, errors are structured just like other Kibo APIs.

```typescript theme={null}
// Actual error structure from Kibo API documentation
interface KiboApiError {
  body: {
    message: string;             // Human-readable description of the error
    errorCode: string;           // A specific code for programmatic handling
    correlationId: string;       // Unique ID for this request, useful for support tickets
  }
}
```

**Common Error Codes for Webhooks:**

* `VALIDATION_ERROR`: The request body for creating/updating a subscription is invalid. This often means the `endpoint` URL is malformed or a `topic` does not exist.
* `ITEM_NOT_FOUND`: You tried to get, update, or check the DLQ for a `subscriptionId` that doesn't exist.
* `REQUIRED_FIELD_MISSING`: Your request to create a subscription is missing a required field like `endpoint` or `topics`.

**Reference:** [Status Codes](/pages/status-codes)

### Common Development Issues

**Issue 1:** My endpoint isn't receiving any events.

* **Why it happens:**
  1. The subscription is marked as `isActive: false`.
  2. Your endpoint URL is incorrect, inaccessible from the public internet, or blocked by a firewall.
  3. Your endpoint is returning an error status code (e.g., 500 Server Error, 400 Bad Request), causing Kibo to stop trying and place the event in the DLQ.
  4. `Disable Callbacks` is enabled.  If the same credentials that are generating the event, are also receiving the event, this will prevent events being emitted.
* **How to fix it:**
  1. Use `getSubscriptionDetails` to verify the subscription is active and the URL is correct.
  2. Use a tool like `ngrok` to expose your local development server to the internet for testing.
  3. **Check the Dead Letter Queue!** Use the `checkDeadLetterQueue` example function. This is the most important debugging step.
  4. Ensure your endpoint returns a `2xx` status code (e.g., `200 OK` or `202 Accepted`) immediately upon receiving an event.

**Issue 2:** How do I know which `topics` are available to subscribe to?

* **Why it happens:** The list of available event topics is extensive and not immediately obvious from the API endpoints for managing subscriptions.
* **How to find it:** The Kibo documentation maintains a list of all available events. Always refer to the official documentation for an up-to-date list before creating a subscription. Creating a subscription with a non-existent topic will result in a `VALIDATION_ERROR`.
* **Reference:** Search for "Kibo Event Topics" on the official Kibo documentation site.

### Debugging Checklist

When your webhook implementation isn't working:

1. **Verify Subscription:** Is the subscription `isActive`? Is the `endpoint` URL publicly accessible and correct?
2. **Check the DLQ:** Is Kibo trying to send events but failing? Use `getDeadLetterEvents` with your `subscriptionId` to find out. This is your primary diagnostic tool.
3. **Inspect Endpoint Logs:** Is your server receiving the `POST` request from Kibo? Is it throwing an unhandled exception?
4. **Confirm Response Code:** Is your endpoint code *always* returning a `200 OK` response, even if your internal processing fails? Acknowledge receipt first, then process.
5. **Validate Topics:** Does the topic you subscribed to (`order.opened`) actually exist in the Kibo documentation?
6. **Check API Credentials:** Are your API calls to manage subscriptions failing? Double-check your `Configuration` object for correct credentials.
