MekanteMekante Developers
Getting started
Till API
Webhooks
llms.txt
  • Türkçe
  • English
Getting started
Till API
Webhooks
llms.txt
  • Türkçe
  • English
  • Getting started

    • Mekante Developers
    • Getting started
    • Authentication
  • Till API

    • Till flow
    • Endpoints
    • Errors
    • Limits
  • Webhooks

    • Webhooks
    • Signature verification

Webhooks

A webhook is an HTTP POST request that Mekante sends to your server whenever an event occurs. This lets you sync memberships, earned points, redemptions, and voids into your own systems (ERP, accounting, CRM, custom messaging) without polling.

Adding an endpoint

Only the business owner can manage webhook endpoints: open Developers (Geliştiriciler) in the dashboard, click New webhook (Yeni webhook), enter your URL, select the events you want to subscribe to, and click Add endpoint (Adres ekle).

  • The URL must be a publicly reachable https address. Local networks, localhost, and private IP ranges (10.x, 192.168.x, 172.16–31.x, loopback, link-local) are rejected both at creation time and before every delivery attempt.
  • The URL must not contain inline credentials (user:pass@).
  • When the endpoint is created, a signing secret (whsec_…) is generated and shown only once. You need it to verify incoming requests (Signature verification). If you lose it, delete the endpoint and create a new one.
  • Choose Send test (Test gönder) from the endpoint's row menu to send a ping event to that endpoint.

Events

EventWhen it fires
member.joinedA customer joins the business's loyalty program
points.earnedPoints or stamps are awarded (POST /earn)
reward.redeemedA reward is redeemed (POST /redeem)
entry.voidedA ledger entry is voided (POST /ledger/:id/void)
pingSent only when you click Send test in the dashboard, regardless of the endpoint's event filter

Each endpoint receives only the events it subscribed to. Events are dispatched after the database transaction commits; a slow or failing webhook never blocks till operations.

Request format

POST /hooks HTTP/1.1
Content-Type: application/json
User-Agent: Mekante-Webhooks/1
X-Mekante-Event: points.earned
X-Mekante-Signature: t=1792749428,v1=794b3947df267c3354af75b5d8931538c765d768e5ca83983dcd52f7c6f93270

Every webhook payload shares the same outer envelope:

FieldDescription
idUnique delivery ID. Remains identical across retry attempts
eventEvent name
createdAtTimestamp when the event occurred (ISO 8601, UTC)
dataEvent-specific payload (shown below)

member.joined

{
  "id": "564c1467-e98d-434d-8722-9ffe766b1eeb",
  "event": "member.joined",
  "createdAt": "2026-10-23T09:57:08.193Z",
  "data": {
    "joinedVia": "join_code",
    "membershipId": "db997e9d-3e8c-469b-b385-6d29633f7c6e",
    "marketingConsent": false
  }
}

joinedVia indicates how the customer enrolled: join_code (scanned a table/counter QR or entered the join code themselves) or till (enrolled at the register via SMS invite link sent by a cashier).

points.earned

{
  "id": "d537115b-5aeb-47cb-9232-8e3df03070da",
  "event": "points.earned",
  "createdAt": "2026-10-23T09:57:08.257Z",
  "data": {
    "membershipId": "db997e9d-3e8c-469b-b385-6d29633f7c6e",
    "points": 150,
    "stamps": 0,
    "balance": 150,
    "stampBalance": 0,
    "entryIds": ["3f99048a-4226-4482-a341-682fe57225b2"]
  }
}

points is the total points awarded in the transaction (including any bonuses), stamps is the total stamps awarded, and balance / stampBalance are the member's new balances.

reward.redeemed

{
  "id": "8b3d35eb-db0c-4a0e-98c8-198e5dddbc8c",
  "event": "reward.redeemed",
  "createdAt": "2026-10-23T09:57:08.336Z",
  "data": {
    "membershipId": "db997e9d-3e8c-469b-b385-6d29633f7c6e",
    "rewardId": "7d5cb889-f95c-4c59-8e7d-a55a92b6113e",
    "code": "WZ86BV",
    "points": -100,
    "stamps": 0,
    "balance": 250,
    "stampBalance": 3
  }
}

entry.voided

data fields: membershipId, entryId (the original entry that was voided), points and stamps (the delta restored or deducted), and balance / stampBalance (the member's updated balances).

ping

{
  "id": "d6cbcbea-9dfc-45fe-8a44-87c5e7f92ed9",
  "event": "ping",
  "createdAt": "2026-10-23T09:57:08.349Z",
  "data": { "hello": "world" }
}

Responding to webhooks

Your endpoint must acknowledge receipt with any 2xx HTTP status code (such as 200). Any other status code, timeout, or connection error is treated as a failed delivery.

  • Respond quickly. Requests time out after 5 seconds. Enqueue heavy processing asynchronously and return 200 immediately.
  • Redirects are not followed. A 301 or 302 response is treated as a failure; point the webhook URL directly at the final destination.

Retries

Failed deliveries are retried with exponential backoff according to this schedule:

AttemptDelay after previous attempt
2nd1 minute
3rd5 minutes
4th30 minutes
5th2 hours
6th12 hours

After the 6th attempt fails, the delivery is marked as failed and no further retries are made (roughly 14.5 hours total).

Handle duplicate deliveries idempotently

Because of retries, your endpoint may receive the same event more than once. The top-level id field is identical across all attempts for the same event: record processed id values and ignore duplicates.

Delivery order is not guaranteed. Order events by createdAt if needed, or rely on the authoritative balance and stampBalance fields included in every event.

Next
Signature verification