Docs Webhooks & Callbacks

Webhooks & Callbacks

What Are Webhooks?

In the real world, APIs do not always respond immediately. When you make a payment, the payment processor returns “accepted” right away, but the actual result (success or failure) arrives later via a webhook – an HTTP request from the server to YOUR application.

Real-world analogy: Ordering food delivery. The app immediately confirms “Order placed!” (the API response). But 30 minutes later, the driver rings your doorbell (the webhook) to tell you the food has arrived. Mockarty callbacks let you simulate both parts of this flow.

Mockarty can automatically fire HTTP requests, Kafka messages, or RabbitMQ messages whenever a mock is matched. This lets you simulate asynchronous notification systems, test webhook receivers, and chain multiple services together – all without writing any code.

Tip: Code examples are available for cURL, CLI, and SDK clients (Go, Python, Java). See the SDK Guide for installation and setup. See the CLI User Guide for the command-line tool.

About URLs in examples: All examples use localhost:5770 as the default Mockarty address. If your instance runs on a remote server, replace localhost:5770 with its actual address (e.g. https://mockarty.company.com or http://192.168.1.50:5770). See Tips & Useful Features for details.

Your App POST /api/payments 1. request Mockarty Mock matched response + trigger webhooks[] 2. response 3. callback HTTP Webhook Receiver Kafka Topic Message RabbitMQ Queue / Exchange on_success on_error always

Trigger modes

$.req.* | $.fake.* | $.gS.* Template engine in body/headers retryCount + retryDelay Automatic retry on failure sync / async Blocking or background

Table of Contents

  1. Business Value
  2. Callback Types
  3. Trigger Modes
  4. HTTP Webhook Configuration
  5. Kafka Callback Configuration
  6. RabbitMQ Callback Configuration
  7. Template Variables in Callbacks
  8. Retry Policy
  9. Sync vs Async Execution
  10. Namespace Webhooks
  11. Admin Webhooks
  12. Examples
  13. Monitoring & Debugging

Business Value

Real-world APIs rarely operate in isolation. A payment gateway notifies your app via webhook. An order service publishes a Kafka event. A shipping service posts to RabbitMQ. Mockarty callbacks let you replicate these patterns in your test environment:

  • Simulate async notifications — mock a Stripe payment endpoint that fires a payment_intent.succeeded webhook to your app.
  • Test webhook receivers — verify your app handles retries, duplicate deliveries, and error payloads correctly.
  • Chain services — mock A calls mock B via webhook, creating multi-step integration test flows without real infrastructure.

Callback Types

Each callback in the webhooks array has a type field:

Type Description Default
http HTTP request to an external URL Yes (if type is omitted)
kafka Publish a message to a Kafka topic No
rabbitmq Publish a message to a RabbitMQ exchange/queue No

Trigger Modes

The trigger field controls when a callback fires based on the mock’s response status code:

Trigger Fires When Status Codes
on_success Response is successful 200–299
on_error Response is an error 400+
always Every matched request Any (default if omitted)
{
  "trigger": "on_success"
}

If trigger is omitted or empty, the callback fires on every matched request (always).


HTTP Webhook Configuration

HTTP is the default callback type. It sends an HTTP request to the specified URL after the mock responds.

Fields

Field Type Required Default Description
type string No "http" Callback type
url string Yes Target URL
method string No "POST" HTTP method: POST, PUT, PATCH, DELETE, GET
headers object No {} Custom HTTP headers
body any No null Request body (supports templating)
timeout int No 30 Timeout in seconds
retryCount int No 0 Number of retry attempts on failure
retryDelay int No 1 Delay between retries in seconds
async bool No false Run asynchronously (non-blocking)
trigger string No "always" When to fire: on_success, on_error, always

Minimal Example

cURL

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "payment-with-webhook",
    "http": {
      "route": "/api/payments",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 200,
      "payload": {
        "id": "$.fake.UUID",
        "status": "succeeded"
      }
    },
    "webhooks": [
      {
        "url": "http://my-app:3000/webhooks/stripe",
        "method": "POST",
        "headers": {
          "X-Stripe-Signature": "t=123456,v1=abc123"
        },
        "body": {
          "type": "payment_intent.succeeded",
          "data": {
            "amount": 2500,
            "currency": "usd"
          }
        },
        "trigger": "on_success"
      }
    ]
  }'

CLI

mockarty-cli mock create --id payment-with-webhook \
  --route /api/payments --method POST \
  --status 200 \
  --payload '{"id":"$.fake.UUID","status":"succeeded"}' \
  --webhook-url http://my-app:3000/webhooks/stripe \
  --webhook-trigger on_success \
  --webhook-body '{"type":"payment_intent.succeeded","data":{"amount":2500,"currency":"usd"}}'

Go

err := client.Mocks().Create(ctx, &mockarty.Mock{
    ID: "payment-with-webhook",
    HTTP: &mockarty.HTTPConfig{
        Route:      "/api/payments",
        HTTPMethod: "POST",
    },
    Response: &mockarty.Response{
        StatusCode: 200,
        Payload: map[string]any{
            "id": "$.fake.UUID", "status": "succeeded",
        },
    },
    Webhooks: []mockarty.Webhook{{
        URL:     "http://my-app:3000/webhooks/stripe",
        Method:  "POST",
        Headers: map[string]string{"X-Stripe-Signature": "t=123456,v1=abc123"},
        Body: map[string]any{
            "type": "payment_intent.succeeded",
            "data": map[string]any{"amount": 2500, "currency": "usd"},
        },
        Trigger: "on_success",
    }},
})

Python

client.mocks.create({
    "id": "payment-with-webhook",
    "http": {"route": "/api/payments", "httpMethod": "POST"},
    "response": {
        "statusCode": 200,
        "payload": {"id": "$.fake.UUID", "status": "succeeded"},
    },
    "webhooks": [{
        "url": "http://my-app:3000/webhooks/stripe",
        "method": "POST",
        "headers": {"X-Stripe-Signature": "t=123456,v1=abc123"},
        "body": {"type": "payment_intent.succeeded", "data": {"amount": 2500, "currency": "usd"}},
        "trigger": "on_success",
    }],
})

Java

client.mocks().create(Mock.builder()
    .id("payment-with-webhook")
    .http(HttpConfig.builder().route("/api/payments").httpMethod("POST").build())
    .response(Response.builder().statusCode(200)
        .payload(Map.of("id", "$.fake.UUID", "status", "succeeded")).build())
    .webhooks(List.of(Webhook.builder()
        .url("http://my-app:3000/webhooks/stripe")
        .method("POST")
        .trigger("on_success")
        .body(Map.of("type", "payment_intent.succeeded",
            "data", Map.of("amount", 2500, "currency", "usd")))
        .build()))
    .build());

Kafka Callback Configuration

Publish a message to a Kafka topic when a mock is matched.

Fields

Field Type Required Default Description
type string Yes Must be "kafka"
kafkaBrokers string Yes Comma-separated broker addresses (e.g. "kafka1:9092,kafka2:9092")
kafkaTopic string Yes Target topic name
kafkaKey string No "" Message key (supports templating)
kafkaUseSASL bool No false Enable SASL/PLAIN authentication
kafkaUsername string No "" SASL username (required if kafkaUseSASL is true)
kafkaPassword string No "" SASL password
kafkaUseTLS bool No false Enable TLS (minimum TLS 1.2)
headers object No {} Kafka message headers (key-value pairs)
body any No null Message value (supports templating)
timeout int No 30 Write timeout in seconds
retryCount int No 0 Number of retry attempts
retryDelay int No 1 Delay between retries in seconds
trigger string No "always" When to fire

Example

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "order-created-kafka",
    "http": {
      "route": "/api/orders",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 201,
      "payload": {
        "orderId": "$.fake.UUID",
        "status": "created"
      }
    },
    "webhooks": [
      {
        "type": "kafka",
        "kafkaBrokers": "localhost:9092",
        "kafkaTopic": "orders.created",
        "kafkaKey": "$.req.customerId",
        "body": {
          "event": "order.created",
          "orderId": "$.fake.UUID",
          "timestamp": "$.fake.UnixTime"
        },
        "trigger": "on_success"
      }
    ]
  }'

Kafka with SASL/TLS

{
  "type": "kafka",
  "kafkaBrokers": "kafka-prod.example.com:9093",
  "kafkaTopic": "events",
  "kafkaUseSASL": true,
  "kafkaUsername": "my-service",
  "kafkaPassword": "secret",
  "kafkaUseTLS": true,
  "body": {"event": "test"},
  "trigger": "always"
}

Note: The Content-Type header is automatically excluded from Kafka message headers. All other entries in headers are passed as Kafka message headers.


RabbitMQ Callback Configuration

Publish a message to a RabbitMQ exchange or queue when a mock is matched.

Fields

Field Type Required Default Description
type string Yes Must be "rabbitmq"
rabbitURL string Yes AMQP connection URI (e.g. "amqp://guest:guest@localhost:5672/")
rabbitExchange string No "" Exchange name (empty = default exchange)
rabbitRoutingKey string No "" Routing key
rabbitQueue string No "" Queue name (used as routing key if exchange and routingKey are empty)
rabbitMandatory bool No false Mandatory flag for publish
headers object No {} AMQP message headers
body any No null Message body (supports templating)
timeout int No 30 Connection timeout in seconds
retryCount int No 0 Number of retry attempts
retryDelay int No 1 Delay between retries in seconds
trigger string No "always" When to fire

Example — Direct Queue

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "notification-rabbitmq",
    "http": {
      "route": "/api/notifications/send",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 200,
      "payload": {"status": "queued"}
    },
    "webhooks": [
      {
        "type": "rabbitmq",
        "rabbitURL": "amqp://guest:guest@localhost:5672/",
        "rabbitQueue": "notifications",
        "body": {
          "type": "email",
          "to": "$.req.email",
          "subject": "Your order has been placed"
        },
        "trigger": "on_success"
      }
    ]
  }'

Example — Exchange with Routing Key

{
  "type": "rabbitmq",
  "rabbitURL": "amqp://guest:guest@localhost:5672/",
  "rabbitExchange": "events",
  "rabbitRoutingKey": "order.created",
  "body": {
    "orderId": "$.fake.UUID"
  }
}

Note: If both rabbitExchange and rabbitRoutingKey are empty but rabbitQueue is set, the queue name is used as the routing key with the default exchange. The Content-Type of the AMQP message defaults to application/json unless overridden in headers.


Template Variables in Callbacks

Callback body and headers fields support the same templating engine as mock responses. You can use:

JsonPath — Extract from the Original Request (full guide)

{
  "body": {
    "userId": "$.req.userId",
    "email": "$.req.email",
    "authToken": "$.reqHeader.Authorization[0]"
  }
}

Faker — Generate Dynamic Data (full reference)

{
  "body": {
    "webhookId": "$.fake.UUID",
    "timestamp": "$.fake.UnixTime",
    "ip": "$.fake.IPv4"
  }
}

Store Values — Access Global/Chain/Mock Stores (documentation)

{
  "body": {
    "sessionId": "$.gS.currentSession",
    "orderId": "$.cS.orderId",
    "tempValue": "$.mS.computed"
  }
}

String Body with Templates

You can use a string body instead of an object. If it contains $. expressions, they are processed:

{
  "body": "Order $.req.orderId has been processed at $.fake.Date"
}

Response Data

Access the mock’s own response fields:

{
  "body": {
    "mockResponseStatus": "$.response.status"
  }
}

Note: $.response refers to the mock’s response payload object. For example, if your mock returns {"status": "ok", "data": {"id": 1}}, then $.response.status resolves to "ok" and $.response.data.id resolves to 1.


Retry Policy

All callback types support automatic retries on failure.

Field Default Description
retryCount 0 Number of additional attempts after the first failure (0 = no retries)
retryDelay 1 Delay between attempts in seconds

Retries use a fixed delay (not exponential backoff). If the context is cancelled during a retry delay, the callback stops immediately.

{
  "url": "http://unreliable-service.example.com/webhook",
  "retryCount": 3,
  "retryDelay": 2,
  "timeout": 10
}

This attempts up to 4 total requests (1 initial + 3 retries), waiting 2 seconds between each attempt, with a 10-second timeout per request.


Sync vs Async Execution

Mode async Behavior
Async true (default) Callback runs in a background goroutine. The mock response is returned immediately.
Sync false Callback runs before the mock response is returned to the caller. Useful when the caller needs to know the callback completed.
{
  "url": "http://my-app.com/webhook",
  "async": true,
  "trigger": "on_success"
}

Warning: Sync callbacks ("async": false) with high timeout or retryCount values will delay the mock response to the client.


Network Security & SSRF Guard

By default Mockarty blocks outbound webhook calls to private, loopback, link-local, and cloud-metadata IP addresses. This is an SSRF guard — without it, a malicious mock configuration could make the Mockarty server probe its own internal network.

Blocked ranges (default):

  • 127.0.0.0/8 (loopback)
  • 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (private IPv4)
  • 169.254.0.0/16 (link-local / cloud metadata endpoints like 169.254.169.254)
  • IPv6 equivalents (::1, fc00::/7, fe80::/10)

Relevant environment variables (set on the resolver, and on the admin node if it serves mocks directly):

Variable Default Description
ALLOW_PROXY_TO_PRIVATE_IPS false When false, the SSRF guard is active and webhook calls to the ranges above are rejected. Set to true ONLY in isolated dev/CI environments where targets legitimately live on private IPs
WEBHOOK_POOL_SIZE 10 Maximum number of concurrent outbound webhook workers per resolver / admin node. This is a node-level throughput cap, not a per-mock limit

Production rule. Leave ALLOW_PROXY_TO_PRIVATE_IPS=false in production. If you need to call an internal service, put it behind a reverse proxy with a public hostname or an explicit allow-list, rather than opening the SSRF guard globally.

About the Stripe-Signature example below. The example in the “Examples” section uses a hardcoded literal string v1=test_signature. Mockarty does NOT compute real HMAC signatures — if you need a valid signature, generate it in your client code before calling the mock and pass it through the request body or via a Store value. Templating is string substitution only.


Namespace Webhooks

Namespace webhooks fire when CRUD operations occur on mocks within a namespace. These are configured separately from per-mock callbacks.

Supported Operations

Operation Fires When
mock.create A mock is created in the namespace
mock.update A mock is updated
mock.delete A mock is deleted
mock.restore A mock is restored from soft-delete
user.add_to_namespace A user is added to the namespace

API Endpoints

# List namespace webhooks
GET /api/v1/namespaces/{namespace}/webhooks

# Create/update a namespace webhook
POST /api/v1/namespaces/{namespace}/webhooks

# Delete a namespace webhook
DELETE /api/v1/namespaces/{namespace}/webhooks/{id}

Example — Notify Slack on Mock Changes

curl -X POST http://localhost:5770/api/v1/namespaces/production/webhooks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "operation": "mock.create",
    "url": "https://hooks.slack.com/services/T.../B.../xxx",
    "method": "POST",
    "body": {
      "text": "New mock created in production namespace"
    },
    "enabled": true,
    "retryCount": 2,
    "retryDelay": 3
  }'

Admin Webhooks

Admin webhooks fire on system-level operations. Only administrators can configure these.

Supported Operations

Operation Fires When
namespace.create A new namespace is created
namespace.delete A namespace is deleted
namespace.update A namespace is updated
namespace.user.add A user is added to a namespace
user.create A new user is created
user.delete A user is deleted
user.update A user is updated
user.password.set A user’s password is changed
job.run A background job is triggered
backup.create A backup is created
backup.restore A backup is restored
license.create A license is created
license.update A license is updated
license.delete A license is deleted

API Endpoints

# List admin webhooks
GET /api/v1/admin/webhooks

# Create/update an admin webhook
POST /api/v1/admin/webhooks

# Delete an admin webhook
DELETE /api/v1/admin/webhooks/{id}

Example — Audit Log on User Creation

curl -X POST http://localhost:5770/api/v1/admin/webhooks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <admin-token>" \
  -d '{
    "operation": "user.create",
    "url": "https://audit.internal.com/events",
    "method": "POST",
    "body": {
      "event": "user.created",
      "source": "mockarty"
    },
    "enabled": true
  }'

Examples

1. Simulate Stripe Webhook on Payment Mock

When your app calls POST /api/payments, Mockarty responds with a success payload and fires a webhook to your app’s Stripe listener:

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "stripe-payment",
    "http": {
      "route": "/api/payments/intents",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 200,
      "payload": {
        "id": "pi_$.fake.UUID",
        "status": "succeeded",
        "amount": "$.req.amount"
      }
    },
    "webhooks": [
      {
        "url": "http://my-app:3000/webhooks/stripe",
        "method": "POST",
        "headers": {
          "Stripe-Signature": "t=$.fake.UnixTime,v1=test_signature",
          "Content-Type": "application/json"
        },
        "body": {
          "id": "evt_$.fake.UUID",
          "type": "payment_intent.succeeded",
          "data": {
            "object": {
              "id": "pi_$.fake.UUID",
              "amount": "$.req.amount",
              "currency": "$.req.currency",
              "status": "succeeded"
            }
          }
        },
        "trigger": "on_success",
        "retryCount": 3,
        "retryDelay": 5,
        "timeout": 15
      }
    ]
  }'

2. Forward Kafka Message on Order Creation

Mock an order API that publishes an event to Kafka for downstream consumers:

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "order-with-kafka-event",
    "http": {
      "route": "/api/orders",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 201,
      "payload": {
        "orderId": "$.fake.UUID",
        "status": "created"
      }
    },
    "webhooks": [
      {
        "type": "kafka",
        "kafkaBrokers": "kafka:9092",
        "kafkaTopic": "orders.events",
        "kafkaKey": "$.req.customerId",
        "headers": {
          "event-type": "order.created",
          "source": "order-service"
        },
        "body": {
          "orderId": "$.fake.UUID",
          "customerId": "$.req.customerId",
          "items": "$.req.items",
          "total": "$.req.total",
          "createdAt": "$.fake.Date"
        },
        "trigger": "on_success"
      }
    ]
  }'

3. Chain: Mock -> Webhook -> Another Mock

Create a two-step flow where a payment mock triggers a notification mock:

Step 1 — Create the notification receiver mock:

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "notification-receiver",
    "http": {
      "route": "/internal/notifications",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 200,
      "payload": {"notified": true}
    },
    "extract": {
      "gStore": {
        "lastNotifiedOrder": "$.req.orderId"
      }
    }
  }'

Step 2 — Create the payment mock that chains to it:

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "payment-with-chain",
    "http": {
      "route": "/api/pay",
      "httpMethod": "POST"
    },
    "response": {
      "statusCode": 200,
      "payload": {
        "paid": true,
        "orderId": "$.req.orderId"
      }
    },
    "webhooks": [
      {
        "url": "http://localhost:5770/stubs/sandbox/internal/notifications",
        "method": "POST",
        "body": {
          "orderId": "$.req.orderId",
          "event": "payment.completed",
          "amount": "$.req.amount"
        },
        "async": false,
        "trigger": "on_success"
      }
    ]
  }'

Now calling POST /api/pay will respond with success and call POST /stubs/sandbox/internal/notifications on the same Mockarty instance, storing the order ID in the global store.

4. Error Webhook — Notify on Failure

Fire a callback only when the mock returns an error:

curl -X POST http://localhost:5770/api/v1/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "id": "flaky-service",
    "http": {
      "route": "/api/fragile",
      "httpMethod": "GET"
    },
    "response": {
      "statusCode": 503,
      "payload": {"error": "service unavailable"}
    },
    "webhooks": [
      {
        "url": "http://alerting-system:8080/alerts",
        "body": {
          "alert": "fragile-service-mock returned error",
          "statusCode": 503
        },
        "trigger": "on_error"
      }
    ]
  }'

5. Multiple Callbacks on One Mock

A single mock can have multiple callbacks of different types:

{
  "webhooks": [
    {
      "type": "http",
      "url": "http://audit.internal/log",
      "body": {"event": "order.created"},
      "trigger": "always"
    },
    {
      "type": "kafka",
      "kafkaBrokers": "kafka:9092",
      "kafkaTopic": "orders.events",
      "body": {"event": "order.created"},
      "trigger": "on_success"
    },
    {
      "type": "rabbitmq",
      "rabbitURL": "amqp://guest:guest@rabbitmq:5672/",
      "rabbitQueue": "notifications",
      "body": {"notify": true},
      "trigger": "on_success"
    }
  ]
}

Monitoring & Debugging

Application Logs

All callback activity is logged via structured logging (Zap). Look for these log messages:

Log Level Message Meaning
INFO Callback executed successfully Callback completed without error
WARN Callback attempt failed A single attempt failed (may retry)
ERROR Callback failed after all retries All attempts exhausted
ERROR Failed to prepare webhook body Template rendering failed
ERROR Panic in webhook executeCallback Unexpected panic (includes stack trace)

Log entries include the callback type (http/kafka/rabbitmq) and the attempt number.

Tips

  1. Use sync mode for debugging — Set "async": false to ensure callbacks complete before the response. This makes the timing predictable in logs.

  2. Start with retryCount: 0 — Add retries only after confirming the callback target is reachable.

  3. Test the target first — Before creating the mock, verify the webhook URL / Kafka broker / RabbitMQ connection is accessible from the Mockarty host:

    # Test HTTP target
    curl -v http://my-app:3000/webhooks/stripe
    
    # Test Kafka connectivity
    kafkacat -b kafka:9092 -L
    
    # Test RabbitMQ connectivity
    curl -u guest:guest http://rabbitmq:15672/api/overview
    
  4. Check callback body templating — If your callback body uses $.req.* expressions, make sure the original request contains the expected fields. Unresolved templates are sent as literal strings.

  5. Timeout tuning — The default 30-second timeout is generous. For local services, 5-10 seconds is usually enough. For external services behind firewalls, increase as needed.

  6. Context cancellation — If the client disconnects before an async callback completes, the callback may be cancelled during retry delays. For critical callbacks, keep retryDelay short.


Common Mistakes

Here are the most frequent issues when setting up callbacks:

  1. Using localhost in the webhook URL when Mockarty is in Docker. Inside Docker, localhost points to the container itself. Use the Docker service name (e.g., http://my-app:3000/webhook) or http://host.docker.internal:3000/webhook to reach the host machine.

  2. Not realizing sync mode delays the response. With "async": false, the mock response is not returned to the caller until the callback completes. If the callback target is slow or unreachable, your test will hang. The default is "async": true (background execution), so only set false when you need the callback to complete before the response.

  3. Setting retryCount too high without thinking about timeout. With retryCount: 5 and timeout: 30, a failing callback will block for up to 150 seconds (5 x 30s). Start with retryCount: 1 and timeout: 5 for local services.

  4. Expecting $.req.* to resolve from the webhook body. The $.req.* expressions refer to the original request that triggered the mock, not the callback request. If you need data from the callback response, it is not currently supported.

  5. Mixing up mock-level and namespace-level webhooks. Mock-level webhooks (in the webhooks array of a mock) fire when that specific mock is matched. Namespace webhooks fire when mocks are created/updated/deleted via the API. They serve different purposes.

  6. Kafka: not specifying the broker address correctly. The kafkaBrokers field must be the address as seen from the Mockarty host. In Docker Compose, use the Kafka service name (e.g., kafka:9092), not localhost:9092.


See Also

  • API Reference – Full REST API documentation including webhook endpoints
  • Faker Reference – All available Faker functions for dynamic callback payloads
  • JsonPath Guide – JsonPath expressions for extracting request data in callbacks
  • Stores – Global, Chain, and Mock store systems used in callback templates
  • Recorder – Record live traffic and generate mocks with webhook configurations
  • Notification Channels – System-level notification channels (Telegram, Slack, Discord, etc.)
  • Chaos Testing – Inject failures and latency alongside webhook callbacks