Core Concepts

Understanding Hook Mesh's mental model will help you integrate faster and use the platform effectively. This guide explains the key concepts and how they relate to each other.

Data Model Overview

Organization
├── Applications
├── Endpoints
└── Webhook Jobs
└── Event Types
├── API Keys
└── Users

Organizations

An organization is the top-level container that represents your company. When you sign up for Hook Mesh, you create an organization.

Organizations contain:

  • Applications - Your products/environments
  • API Keys - For authentication
  • Users - Team members with access
  • Billing information - Subscription and usage
Multi-tenancy: All API requests are scoped to your organization. You can't access another organization's data, even if you know the resource IDs.

Applications

An application represents one of your products or environments. Most organizations have at least two applications: one for production and one for testing/staging.

Example setup:

  • Production App - Live customer webhooks
  • Staging App - Testing before deployment
  • Development App - Local development

Each application has its own:

  • Endpoints - Customer webhook URLs
  • Event Types - Schema for webhook payloads
  • Portal Configuration - Branding for customer portal

Event Types

Event types define the kinds of webhooks your application can send. They act as a schema and help customers understand what events are available.

Naming Conventions

✅ Good names
  • user.created
  • invoice.paid
  • subscription.canceled
  • document.signed
❌ Avoid
  • createUser - Imperative, not past tense
  • USER_CREATED - Uppercase
  • new-user - Unclear action

Best practice: Use dot notation with the format resource.action in lowercase with past tense.

Schemas

You can optionally define JSON schemas for event types. This helps with documentation and will enable payload validation in the future.

{
  "name": "user.created",
  "description": "Fired when a new user signs up",
  "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"]
  }
}

Endpoints

Endpoints are your customers' webhook URLs. Each endpoint represents one destination for webhook delivery.

Endpoint Properties

PropertyDescription
urlHTTPS URL to receive webhooks
secretHMAC secret for signature verification
subscribed_eventsArray of event types to receive
statusactive, disabled, or paused
circuit_stateclosed, open, or half-open
rate_limitMax requests per second

Event Subscriptions

Endpoints subscribe to specific event types. When you send a webhook for an event type, Hook Mesh delivers it only to endpoints that have subscribed to that event.

Endpoint with event subscriptions
{
  "url": "https://customer.com/webhooks",
  "subscribed_events": [
    "user.created",
    "user.updated",
    "invoice.paid"
  ]
}
Customers control subscriptions: Your customers can use the portal to select which events they want to receive, reducing noise and improving their experience.

Webhook Jobs

A webhook job represents a single delivery task. When you send a webhook event, Hook Mesh creates a job for each endpoint that subscribes to that event type.

Job Lifecycle

created→ Job queued for delivery
executing→ Currently being delivered
succeeded→ Received 2xx response
awaiting_retry→ Failed, will retry
discarded→ Max retries or expired
archived→ Soft-deleted

Job Properties

{
  "id": "job_5nM8pQ1rK3vL9xB",
  "application_id": "app_2Zy3X8qP9rK5mN1vB",
  "event_type": "user.created",
  "event_id": "evt_unique_123",
  "status": "succeeded",
  "attempt_count": 1,
  "max_retries": 6,
  "payload": {...},
  "headers": {...},
  "created_at": "2026-01-20T15:30:00Z",
  "expires_at": "2026-01-22T15:30:00Z",
  "completed_at": "2026-01-20T15:30:05Z"
}

Delivery Window

Each job has a 48-hour delivery window from creation. If the webhook isn't successfully delivered within this window, the job is marked as discarded.

Important: The 48-hour window includes all retry attempts. If your customer's endpoint is down for more than 48 hours, webhooks during that time will be discarded.

Idempotency

Hook Mesh provides two IDs for handling duplicate webhooks:

Webhook ID

Every webhook job has a unique Webhook-Id header. This is Hook Mesh's internal ID for the delivery.

POST /webhooks HTTP/1.1
Webhook-Id: job_5nM8pQ1rK3vL9xB
Webhook-Timestamp: 1737380400
Webhook-Signature: v1,g0hM9SsE+OTPJTGt...

Event ID (Optional)

You can provide your own event_id when creating webhook jobs. This helps you prevent duplicate job creation.

Webhook job with event ID
{
  "application_id": "app_xyz",
  "event_type": "invoice.paid",
  "event_id": "inv_123_paid",
  "payload": {...}
}

If you send the same event_id within 24 hours, Hook Mesh returns the existing job instead of creating a new one.

Best practice: Use both IDs - event_id to prevent duplicate sends, and Webhook-Id for your customers to prevent duplicate processing.

Delivery Flow

Here's what happens when you send a webhook:

1

You send webhook job

POST to /v1/webhook-jobs with event type and payload

2

Hook Mesh finds subscribers

Looks up all endpoints subscribed to that event type

3

Jobs created and queued

One job per endpoint, status: created

4

Delivery attempt

HTTP POST with signed payload to customer endpoint

5

Success or retry

2xx → succeeded | 4xx/5xx → awaiting_retry

6

Retries if needed

Up to 6 retries over 48 hours with exponential backoff

What's next?

Now that you understand the core concepts, dive into specific topics: