Event Types API
Event types define the categories of events your application sends via webhooks. Use this API to create, manage, and organize event types with optional JSON schemas for validation.
The Event Type Object
Event types are named categories that endpoints can subscribe to. Each event type optionally includes a JSON schema for payload validation.
Attributes
- idstring
- Unique identifier for the event type (KSUID format)
- org_idstring
- Organization that owns this event type
- namestring
- Event type name in
resource.actionformat (lowercase, past tense) - descriptionstring | null
- Human-readable description of when this event fires
- schemaobject | null
- Optional JSON Schema for payload validation
- subscriber_countinteger
- Number of endpoints subscribed to this event type
- created_atstring
- ISO 8601 timestamp when the event type was created
- updated_atstring
- ISO 8601 timestamp when the event type was last updated
{
"id": "evt_2Zy3X8a9b0c1d2e3f4g5h6i7",
"org_id": "org_xyz789",
"name": "user.created",
"description": "Fired when a new user account is created",
"schema": {
"type": "object",
"properties": {
"user_id": { "type": "string" },
"email": { "type": "string", "format": "email" },
"created_at": { "type": "string", "format": "date-time" }
},
"required": ["user_id", "email", "created_at"]
},
"subscriber_count": 12,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T10:30:00Z"
}Create an Event Type
Define a new event type with an optional JSON schema for payload validation.
POST /v1/event-typesParameters
| Field | Type | Description |
|---|---|---|
| name | string | requiredEvent type name (lowercase.dot.notation) |
| description | string | Human-readable description |
| schema | object | JSON Schema for validation |
import fetch from 'node-fetch';
const response = await fetch('https://api.hookmesh.com/v1/event-types', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'payment.succeeded',
description: 'Fired when a payment is successfully processed',
schema: {
type: 'object',
properties: {
payment_id: { type: 'string' },
amount: { type: 'number', minimum: 0 },
currency: { type: 'string', pattern: '^[A-Z]{3}$' },
customer_id: { type: 'string' }
},
required: ['payment_id', 'amount', 'currency', 'customer_id']
}
})
});
const eventType = await response.json();
console.log('Event type created:', eventType.id);import requests
import os
response = requests.post(
'https://api.hookmesh.com/v1/event-types',
headers={
'Authorization': f'Bearer {os.environ["HOOKMESH_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'name': 'payment.succeeded',
'description': 'Fired when a payment is successfully processed',
'schema': {
'type': 'object',
'properties': {
'payment_id': {'type': 'string'},
'amount': {'type': 'number', 'minimum': 0},
'currency': {'type': 'string', 'pattern': '^[A-Z]{3}$'},
'customer_id': {'type': 'string'}
},
'required': ['payment_id', 'amount', 'currency', 'customer_id']
}
}
)
event_type = response.json()
print(f'Event type created: {event_type["id"]}')package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
type EventTypeRequest struct {
Name string `json:"name"`
Description string `json:"description"`
Schema map[string]interface{} `json:"schema"`
}
func main() {
payload := EventTypeRequest{
Name: "payment.succeeded",
Description: "Fired when a payment is successfully processed",
Schema: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"payment_id": map[string]string{"type": "string"},
"amount": map[string]interface{}{"type": "number", "minimum": 0},
"currency": map[string]string{"type": "string", "pattern": "^[A-Z]{3}$"},
"customer_id": map[string]string{"type": "string"},
},
"required": []string{"payment_id", "amount", "currency", "customer_id"},
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.hookmesh.com/v1/event-types", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("HOOKMESH_API_KEY"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var eventType map[string]interface{}
json.NewDecoder(resp.Body).Decode(&eventType)
fmt.Printf("Event type created: %s\n", eventType["id"])
}<?php
$ch = curl_init('https://api.hookmesh.com/v1/event-types');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HOOKMESH_API_KEY'),
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'payment.succeeded',
'description' => 'Fired when a payment is successfully processed',
'schema' => [
'type' => 'object',
'properties' => [
'payment_id' => ['type' => 'string'],
'amount' => ['type' => 'number', 'minimum' => 0],
'currency' => ['type' => 'string', 'pattern' => '^[A-Z]{3}$'],
'customer_id' => ['type' => 'string']
],
'required' => ['payment_id', 'amount', 'currency', 'customer_id']
]
])
]);
$response = curl_exec($ch);
$eventType = json_decode($response, true);
echo "Event type created: {$eventType['id']}\n";
curl_close($ch);List Event Types
Retrieve all event types for your organization, optionally filtered by name.
GET /v1/event-typesQuery Parameters
| Parameter | Type | Description |
|---|---|---|
| limit | integer | Number of results per page (default: 20, max: 100) |
| cursor | string | Pagination cursor from previous response |
| search | string | Filter by event type name (partial match) |
const response = await fetch(
'https://api.hookmesh.com/v1/event-types?limit=50&search=payment',
{
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`
}
}
);
const { data, next_cursor } = await response.json();
console.log(`Found ${data.length} event types`);response = requests.get(
'https://api.hookmesh.com/v1/event-types',
headers={'Authorization': f'Bearer {os.environ["HOOKMESH_API_KEY"]}'},
params={'limit': 50, 'search': 'payment'}
)
result = response.json()
print(f'Found {len(result["data"])} event types')package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET",
"https://api.hookmesh.com/v1/event-types?limit=50&search=payment",
nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("HOOKMESH_API_KEY"))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
data := result["data"].([]interface{})
fmt.Printf("Found %d event types\n", len(data))
}<?php
$url = 'https://api.hookmesh.com/v1/event-types?' . http_build_query([
'limit' => 50,
'search' => 'payment'
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HOOKMESH_API_KEY')
]
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
echo "Found " . count($result['data']) . " event types\n";
curl_close($ch);Retrieve an Event Type
Get details for a specific event type by ID.
GET /v1/event-types/:idconst eventTypeId = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7';
const response = await fetch(
`https://api.hookmesh.com/v1/event-types/${eventTypeId}`,
{
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`
}
}
);
const eventType = await response.json();
console.log('Event type:', eventType.name);
console.log('Subscribers:', eventType.subscriber_count);event_type_id = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7'
response = requests.get(
f'https://api.hookmesh.com/v1/event-types/{event_type_id}',
headers={'Authorization': f'Bearer {os.environ["HOOKMESH_API_KEY"]}'}
)
event_type = response.json()
print(f'Event type: {event_type["name"]}')
print(f'Subscribers: {event_type["subscriber_count"]}')package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
eventTypeID := "evt_2Zy3X8a9b0c1d2e3f4g5h6i7"
req, _ := http.NewRequest("GET",
"https://api.hookmesh.com/v1/event-types/"+eventTypeID,
nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("HOOKMESH_API_KEY"))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var eventType map[string]interface{}
json.NewDecoder(resp.Body).Decode(&eventType)
fmt.Printf("Event type: %s\n", eventType["name"])
fmt.Printf("Subscribers: %.0f\n", eventType["subscriber_count"])
}<?php
$eventTypeId = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7';
$ch = curl_init("https://api.hookmesh.com/v1/event-types/{$eventTypeId}");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HOOKMESH_API_KEY')
]
]);
$response = curl_exec($ch);
$eventType = json_decode($response, true);
echo "Event type: {$eventType['name']}\n";
echo "Subscribers: {$eventType['subscriber_count']}\n";
curl_close($ch);Update an Event Type
Update the description or schema for an event type. The name cannot be changed.
PATCH /v1/event-types/:idSchema Changes
Changing the schema can break existing integrations. Use additive-only changes (add optional fields) or create a new versioned event type instead.
const eventTypeId = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7';
const response = await fetch(
`https://api.hookmesh.com/v1/event-types/${eventTypeId}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: 'Fired when a payment is successfully processed and settled',
schema: {
type: 'object',
properties: {
payment_id: { type: 'string' },
amount: { type: 'number', minimum: 0 },
currency: { type: 'string', pattern: '^[A-Z]{3}$' },
customer_id: { type: 'string' },
// New optional field (additive change - safe)
settlement_date: { type: 'string', format: 'date-time' }
},
required: ['payment_id', 'amount', 'currency', 'customer_id']
}
})
}
);
const updated = await response.json();
console.log('Event type updated:', updated.id);event_type_id = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7'
response = requests.patch(
f'https://api.hookmesh.com/v1/event-types/{event_type_id}',
headers={
'Authorization': f'Bearer {os.environ["HOOKMESH_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'description': 'Fired when a payment is successfully processed and settled',
'schema': {
'type': 'object',
'properties': {
'payment_id': {'type': 'string'},
'amount': {'type': 'number', 'minimum': 0},
'currency': {'type': 'string', 'pattern': '^[A-Z]{3}$'},
'customer_id': {'type': 'string'},
# New optional field (additive change - safe)
'settlement_date': {'type': 'string', 'format': 'date-time'}
},
'required': ['payment_id', 'amount', 'currency', 'customer_id']
}
}
)
updated = response.json()
print(f'Event type updated: {updated["id"]}')Delete an Event Type
Permanently delete an event type. This operation fails if any endpoints are subscribed to this event type.
DELETE /v1/event-types/:idDeletion Constraints
You cannot delete an event type if any endpoints are subscribed to it. Remove all subscriptions first, or use the force=true parameter to unsubscribe all endpoints automatically.
const eventTypeId = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7';
// Check subscriber count first
const eventType = await fetch(
`https://api.hookmesh.com/v1/event-types/${eventTypeId}`,
{
headers: { 'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}` }
}
).then(r => r.json());
if (eventType.subscriber_count > 0) {
console.warn(`${eventType.subscriber_count} endpoints subscribed - use force=true`);
}
// Delete with force to unsubscribe all endpoints
const response = await fetch(
`https://api.hookmesh.com/v1/event-types/${eventTypeId}?force=true`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`
}
}
);
console.log('Event type deleted');event_type_id = 'evt_2Zy3X8a9b0c1d2e3f4g5h6i7'
# Check subscriber count first
event_type = requests.get(
f'https://api.hookmesh.com/v1/event-types/{event_type_id}',
headers={'Authorization': f'Bearer {os.environ["HOOKMESH_API_KEY"]}'}
).json()
if event_type['subscriber_count'] > 0:
print(f'{event_type["subscriber_count"]} endpoints subscribed - using force=true')
# Delete with force to unsubscribe all endpoints
response = requests.delete(
f'https://api.hookmesh.com/v1/event-types/{event_type_id}',
headers={'Authorization': f'Bearer {os.environ["HOOKMESH_API_KEY"]}'},
params={'force': True}
)
print('Event type deleted')Common Patterns
Schema Validation
Use JSON Schema to enforce payload structure and catch errors early.
await fetch('https://api.hookmesh.com/v1/event-types', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'order.shipped',
description: 'Fired when an order is shipped to the customer',
schema: {
type: 'object',
properties: {
order_id: { type: 'string', pattern: '^ord_[a-zA-Z0-9]{20}$' },
tracking_number: { type: 'string', minLength: 10 },
carrier: { type: 'string', enum: ['USPS', 'FedEx', 'UPS', 'DHL'] },
estimated_delivery: { type: 'string', format: 'date-time' },
items: {
type: 'array',
items: {
type: 'object',
properties: {
sku: { type: 'string' },
quantity: { type: 'integer', minimum: 1 }
},
required: ['sku', 'quantity']
},
minItems: 1
}
},
required: ['order_id', 'tracking_number', 'carrier', 'items'],
additionalProperties: false // Reject unknown fields
}
})
});Versioning Strategy
For breaking changes, create a new versioned event type instead of modifying the existing one.
// Create v2 with breaking changes (new required field)
await fetch('https://api.hookmesh.com/v1/event-types', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'user.created.v2',
description: 'Fired when a new user account is created (v2 with role)',
schema: {
type: 'object',
properties: {
user_id: { type: 'string' },
email: { type: 'string', format: 'email' },
role: { type: 'string', enum: ['admin', 'user', 'guest'] }, // New required field
created_at: { type: 'string', format: 'date-time' }
},
required: ['user_id', 'email', 'role', 'created_at'] // role is now required
}
})
});
// Keep user.created.v1 for backward compatibility
// Migrate customers gradually to v2Bulk Event Type Creation
Create multiple event types at once during initial setup.
const eventTypes = [
{ name: 'user.created', description: 'New user account created' },
{ name: 'user.updated', description: 'User profile updated' },
{ name: 'user.deleted', description: 'User account deleted' },
{ name: 'payment.succeeded', description: 'Payment processed successfully' },
{ name: 'payment.failed', description: 'Payment processing failed' },
{ name: 'subscription.created', description: 'New subscription started' },
{ name: 'subscription.canceled', description: 'Subscription canceled' }
];
const results = await Promise.all(
eventTypes.map(eventType =>
fetch('https://api.hookmesh.com/v1/event-types', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.HOOKMESH_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(eventType)
}).then(r => r.json())
)
);
console.log(`Created ${results.length} event types`);Best Practices
- ✓Use lowercase.dot.notation - Keep event type names consistent and readable (
order.shipped) - ✓Use past tense - Events describe completed actions (
user.creatednotuser.create) - ✓Define schemas early - Catch payload errors before they reach your customers
- ✓Use additive-only changes - Only add optional fields to schemas, never remove or change existing fields
- ✓Version for breaking changes - Create
event.name.v2instead of modifying existing schemas - ✓Check subscriber_count - Before making changes, know how many endpoints depend on this event type
- ✓Document your events - Write clear descriptions so customers understand when events fire
- ✓Group related events - Use consistent resource names (
payment.succeeded,payment.failed,payment.refunded)
Related Documentation
Event Types Guide →
Learn about event type naming conventions, versioning strategies, and schema design
Endpoints API →
Subscribe endpoints to specific event types to filter webhook deliveries
Creating Webhook Jobs →
Send webhook events with the event_type field referencing your event types
Payloads & Metadata →
Structure webhook payloads that match your event type schemas