ProBusinessEnterprise

Webhooks: events and signature verification

Overview

Webhooks allow you to receive notifications about events on the tikento platform in real time. When an event occurs (new registration, successful payment, event cancellation), tikento sends an HTTP POST request to your URL with the event data.

Webhooks are available on Pro, Business, and Enterprise plans.

Setup

Adding a webhook URL

  1. Open Settings in the sidebar menu.
  2. Go to the "Integrations" section.
  3. Click "Add webhook".
  4. Enter the endpoint URL (HTTPS required).
  5. Select the event types you want to receive.
  6. Click "Save".

After saving, tikento will send a test request to the specified URL to verify availability.

Webhook secret

When creating a webhook, the system generates a webhook secret -- a string for signature verification. Save it in a secure location. The secret is shown only once.

Event types

EventDescription
registration.createdNew registration created
registration.updatedRegistration data updated (status, fields)
payment.completedPayment successfully completed
payment.refundedPayment refunded
event.publishedEvent published
event.cancelledEvent cancelled

You can subscribe to all types or select only the ones you need in the integration settings.

Payload format

Each webhook is sent as an HTTP POST with a JSON body.

Request headers

HeaderDescription
Content-Typeapplication/json
X-Tikento-EventEvent type (e.g., registration.created)
X-Tikento-SignatureHMAC-SHA256 signature of the request body
X-Tikento-TimestampUnix timestamp of sending (seconds)
X-Tikento-Request-IdUnique request identifier

Body structure

{
  "event": "registration.created",
  "timestamp": "2026-06-30T14:30:00Z",
  "requestId": "req_01912345abcdef",
  "data": {
    "id": "01912345-6789-7abc-def0-123456789abc",
    "event_id": "01900000-0000-7000-0000-000000000001",
    "status": "registered",
    "fields": {
      "registrant_email": "user@example.com",
      "first_name": "Ivan",
      "last_name": "Petrov"
    },
    "created_at": "2026-06-30T14:30:00Z"
  }
}

The requestId field is present in every webhook. Use it for deduplication and when contacting support.

Payload examples by event type

registration.created

{
  "event": "registration.created",
  "timestamp": "2026-06-30T14:30:00Z",
  "requestId": "req_01912345abcdef",
  "data": {
    "id": "01912345-6789-7abc-def0-123456789abc",
    "event_id": "01900000-0000-7000-0000-000000000001",
    "event_slug": "tech-conference-2026",
    "status": "registered",
    "ticket_definition_id": "01900000-0000-7000-0000-000000000010",
    "fields": {
      "registrant_email": "user@example.com",
      "first_name": "Ivan",
      "last_name": "Petrov",
      "company": "Acme Corp"
    },
    "created_at": "2026-06-30T14:30:00Z"
  }
}

payment.completed

{
  "event": "payment.completed",
  "timestamp": "2026-06-30T14:31:00Z",
  "requestId": "req_01912345abcdf0",
  "data": {
    "id": "01912345-6789-7abc-def0-000000000099",
    "registration_id": "01912345-6789-7abc-def0-123456789abc",
    "amount": 5000,
    "currency": "RUB",
    "method": "card",
    "gateway": "yookassa",
    "idempotency_key": "idem_abc123",
    "completed_at": "2026-06-30T14:31:00Z"
  }
}

event.cancelled

{
  "event": "event.cancelled",
  "timestamp": "2026-06-30T15:00:00Z",
  "requestId": "req_01912345abcdf1",
  "data": {
    "id": "01900000-0000-7000-0000-000000000001",
    "slug": "tech-conference-2026",
    "title": "Tech Conference 2026",
    "cancelled_at": "2026-06-30T15:00:00Z",
    "reason": "Venue unavailable"
  }
}

Signature verification

Each webhook is signed using HMAC-SHA256. Signature verification ensures the request was sent by tikento, not an attacker.

Algorithm

  1. Retrieve the X-Tikento-Timestamp and X-Tikento-Signature header values.
  2. Construct the signing string: <timestamp>.<body>, where body is the raw request body.
  3. Compute the HMAC-SHA256 of this string with your webhook secret.
  4. Compare the result with X-Tikento-Signature in hex format.

Node.js example

const crypto = require('crypto');

function verifySignature(body, timestamp, signature, secret) {
  const payload = `${timestamp}.${body}`;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  // Constant-time comparison for protection against timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Python example

import hmac
import hashlib

def verify_signature(body: str, timestamp: str, signature: str, secret: str) -> bool:
    payload = f"{timestamp}.{body}"
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Replay attack protection

Check the X-Tikento-Timestamp: if it is older than 5 minutes, reject the request. This prevents reuse of intercepted webhooks.

Retry policy

If your endpoint does not respond with HTTP 2xx, tikento retries delivery:

AttemptDelay
1Immediately
2After 1 minute
3After 5 minutes
4After 30 minutes

If all 4 attempts (initial + 3 retries) are unsuccessful, the event is marked as failed. You will see a list of failed webhooks in Settings - Integrations - Delivery history.

What counts as success

  • HTTP 200, 201, 202, 204 -- delivery is considered successful.
  • Timeout: a response must be received within 10 seconds.

What counts as an error

  • HTTP 4xx (except 410) -- retry, possible issue on the receiver's side.
  • HTTP 5xx -- retry with delay.
  • Timeout (no response within 10 seconds) -- retry.
  • HTTP 410 (Gone) -- the webhook is automatically disabled, no retries.

Deduplication

Due to retries, your endpoint may receive the same event multiple times. Use requestId from the payload for deduplication:

  1. When receiving a webhook, check if you have already processed this requestId.
  2. If yes -- return HTTP 200 without reprocessing.
  3. If no -- process and save the requestId.

Recommendations

Quick response

Send HTTP 200 immediately upon receiving the request. Perform long-running processing asynchronously (queue, background task). This reduces the risk of timeouts and retries.

Idempotency

Design your handler so that reprocessing the same event does not cause duplicate actions (double email sends, duplicate charges, etc.).

Logging

Save the requestId, X-Tikento-Event, and timestamp of each received webhook. This helps with debugging and when contacting support.

Security

  • Accept webhooks only over HTTPS.
  • Always verify the signature via HMAC-SHA256.
  • Check the timestamp for replay attack protection.
  • Store the webhook secret in environment variables, not in code.

Frequently asked questions

Which plans support webhooks?
Webhooks are available on Pro, Business, and Enterprise plans. On the free plan, webhooks are not available -- use manual export or the public API.
How many times does tikento retry delivery on error?
Three retries with exponential backoff: after 1 minute, after 5 minutes, after 30 minutes. If all three retries fail, the event is marked as failed.
How do I verify a webhook signature?
Compute an HMAC-SHA256 of the request body with your webhook secret and compare it to the X-Tikento-Signature header. Use constant-time comparison for protection against timing attacks.
Can I configure multiple webhook URLs?
Yes. In Settings - Integrations, you can add multiple URLs and choose which event types to send to each one.