Skip to main content
Tilta webhooks deliver real-time event notifications to your backend as HTTP POST requests whenever something meaningful happens – a credit facility is approved, an order is confirmed, or an invoice becomes due. Instead of polling the API, you register an endpoint and Tilta pushes updates to you automatically, keeping your platform in sync without unnecessary API calls.

How webhooks work

When a subscribed event occurs, Tilta sends an HTTP POST request to your registered endpoint with a JSON body describing the event. Your endpoint must respond with an HTTP 2xx status code within a reasonable timeout to acknowledge receipt. If it does not, Tilta will retry the delivery automatically.

Event object structure

Every webhook payload follows the same envelope structure regardless of event type:
string
required
A UUID uniquely identifying this event delivery. Use this field to implement idempotency – log processed IDs and skip any event you have already handled.
integer
required
Unix timestamp (seconds) of when the event occurred on Tilta’s side. Use this alongside the resource ID to determine the most recent state when events arrive out of order.
string
required
The dot-separated event type in RESOURCE.PROCESS.OUTCOME format – for example, FACILITY.CREATION.ACCEPTED or ORDER.CONFIRMED. See the Event Reference for all available types.
object
required
Event-specific payload. The fields present depend on the event type. Refer to the Event Reference for the exact shape of each event’s data.

Event subscriptions

Tilta uses a hierarchical dot-separated naming convention – RESOURCE.PROCESS.OUTCOME – which allows you to subscribe at any level of specificity. A subscription to a prefix automatically receives all descendant events. Subscribe only to the events your integration actually needs. Broad prefix subscriptions are convenient but increase the volume of webhook traffic your endpoint must handle.

Setting up a webhook endpoint

1

Build and deploy your endpoint

Create an HTTPS endpoint on your server that accepts POST requests and returns a 2xx HTTP status code promptly. Perform any heavy processing asynchronously after acknowledging receipt – do not block the response while you process the event.
2

Register your endpoint with Tilta

Call POST /v1/webhooks to subscribe your endpoint to one or more event types. The type field accepts either a full event type or a prefix.
Tilta returns a subscription object that includes your signing secret. Store this secret securely – you will use it to verify incoming webhook signatures.
3

Implement signature verification

Every webhook request includes a Tilta-Signature header. Verify this signature before processing any event to ensure the request genuinely came from Tilta. See Signature Verification below for the full implementation.
4

Test with the sandbox

Use the sandbox base URL (https://api.tilta-sandbox.io) to register test endpoints and trigger events without affecting production data. Verify that your endpoint correctly receives, validates, and processes events before going live.

Signature verification

Tilta signs every webhook request so you can confirm it originated from Tilta and has not been tampered with. The signature is included in the Tilta-Signature HTTP header.

Signature header format

The header contains two comma-separated fields:
  • t – Unix timestamp (seconds) of when Tilta signed the request
  • v1 – HMAC-SHA256 hex digest of {webhookPayload}.{webhookTimestamp}, signed with your webhook signing secret

How to verify

To verify a signature, reconstruct the expected HMAC using the raw request body, the timestamp from the header, and your signing secret. Compare the result to the v1 value in the header using a timing-safe comparison to prevent timing attacks.
Always reject webhook requests where the timestamp (t) is more than 5 minutes old. Tilta includes this timestamp so you can protect against replay attacks – where a legitimate captured request is resent maliciously. If you skip this check, an attacker could replay a valid past event to trigger duplicate processing on your platform.

Rotating signing keys

Rotate your webhook signing secret periodically to limit the blast radius of a potential secret leak. Call the rotate endpoint and update your application configuration with the new secret before the old one expires.

Retry behavior

If your endpoint does not return a 2xx response – whether due to a server error, timeout, or any other failure – Tilta automatically retries the delivery. Retries continue for up to 12 hours using exponential backoff, giving your platform time to recover from transient outages without losing events.
Because retries can result in the same event being delivered more than once, always implement idempotency in your event handler. Log each processed event id and skip any event whose id you have already seen.

Managing subscriptions

List your subscriptions

Replace a subscription

Use PUT /v1/webhooks/{type} to update the endpoint URL or configuration for an existing subscription.

Unsubscribe


Best practices

The same event can be delivered more than once due to retries. Before processing any event, check whether you have already handled an event with the same id. Store processed event IDs in a durable store (database, Redis, etc.) and skip duplicates. This prevents double-charging, duplicate fulfillment, or other unintended side effects.
Broad prefix subscriptions (e.g., subscribing to FACILITY instead of FACILITY.CREATION.ACCEPTED) send your endpoint every descendant event, including ones you may not care about. This increases traffic and processing load unnecessarily. Subscribe to the most specific type that covers your use case.
Tilta does not guarantee that events arrive in chronological order. Network conditions and retry timing can cause earlier events to arrive after later ones. Always use the occurred_at timestamp combined with the resource’s external ID to determine the current state of a resource – do not rely solely on arrival order.
Your endpoint should acknowledge receipt by returning 200 OK as fast as possible. Push the event onto a queue and process it in a background worker. If your handler performs slow database writes or downstream API calls synchronously, it risks timing out and causing Tilta to retry an event you have already received.
Treat your webhook signing secret like a password. Rotate it on a regular schedule using POST /v1/webhooks/{type}/signature_key. Update your deployed secret before discarding the old one to avoid a gap in verification. Store secrets in environment variables or a secrets manager – never hardcode them in source code.

API reference