Skip to content

Webhooks API

Webhooks send HTTPS POST requests to your endpoint when events happen in your Cloud. Each request contains a JSON payload for one event, such as a new customer, an approved booking, or a captured payment. Delivery is asynchronous and usually begins within seconds.

Use REV23 on Zapier if you do not need to host your own endpoint. Webhooks & Integrations compares the options.

Events are grouped by category. Sales, Payroll, and Booking events require the corresponding feature. REV23 omits events for disabled features from the subscription picker.

EventFires when
customer.createdA new customer is created
customer.updatedA customer is updated
idea.createdA customer submits an idea
idea.declinedAn idea is declined
EventFires when
service.createdA new service is created
service.completedA service is marked complete
service.user_assignedAn artist is assigned to a service
service_session.createdA new session is created
service_session.startedA session is started
service_session.endedA session ends
EventFires when
release_form.signedA customer signs a release form
release_form.generatedA release form PDF is generated
care_journey.startedA care journey begins
care_journey.review_submittedA customer submits a care review
EventFires when
checkout.completedA checkout is completed
checkout.voidedA checkout is voided
checkout.refundedA checkout is refunded
payment.capturedA payment is captured
payment.voidedA payment is voided
payment.refundedA payment is refunded
credit.createdStore or deposit credit is issued
credit.redeemedCredit is applied to a sale
gift_card.createdA gift card is issued
gift_card.redeemedA gift card is redeemed
EventFires when
pay_period.closedA pay period is closed
payout.processedA payout is recorded
earning.createdAn earning is recorded
earning.reversedAn earning is reversed
EventFires when
booking.createdA booking is created
booking.updatedA booking is updated
booking.rescheduledA booking is moved to a new time
booking.rebookedA cancelled, no-show, or lapsed booking is rebooked
booking.pending_approvalA booking request is waiting on approval
booking.approvedA booking is approved
booking.cancelledA booking is cancelled
booking.declinedA booking request is declined
booking.noshowA booking is marked a no-show
booking.convertedA booking is converted into a service
EventFires when
user.createdA new user is created

The same catalog is available at GET /api/v2/webhooks/events. Each result contains the event slug, display name, category, and required feature.

Each subscription belongs to the user who created it. Most events apply to the entire Cloud, so every active subscription for that event receives them.

These events are scoped to the assigned user:

EventAssigned user
idea.createdArtist assigned to the idea
service.*, service_session.*, release_form.*Artist assigned to the service
care_journey.startedArtist assigned to the service
payout.processed, earning.*Payout or earning recipient

A subscription receives a user-scoped event when its creator is the assigned user, the Cloud owner, or a user with Webhooks → Subscribe (All). If the source record has no assigned user, every active subscription for that event receives it.

All other events in the catalog are Cloud-wide.

Go to Settings → Integrations → Webhooks. A subscription contains:

  • Events — One or more events sent to the same endpoint.
  • URL — The HTTPS endpoint that receives the POST requests.
  • Active — Whether REV23 sends events for this subscription.
  • Custom Headers — Optional headers included with every attempt, such as an authorization header for your endpoint.

REV23 generates a signing secret when you create the subscription. You can reveal or copy it from the subscription later. Use it to verify each request.

You can edit, deactivate, or delete a subscription from the same page. Recent Deliveries lists the latest 50 attempts across your subscriptions, including the request body, result, HTTP status code, and response body.

Every delivery uses the same JSON envelope. The event-specific payload lives in data.

This is an abridged customer.created delivery from Midnight Matinee Tattoo. The full data object contains more customer fields.

{
"type": "customer.created",
"id": "whe_9m4k2p7x6q1a",
"version": 2,
"createdOnUtc": "2026-08-25T10:30:00+00:00",
"tenantName": "midnightmatinee",
"data": {
"id": "cus_4f8m2k9p7x6q",
"givenName": "Verity",
"familyName": "Blackwood",
"fullName": "Verity Blackwood",
"email": "verity.blackwood@example.com",
"createdOnUtc": "2026-08-25T10:29:58+00:00"
}
}
FieldMeaning
typeEvent slug. Use it to route events handled by the same endpoint.
idWebhook event ID. It remains the same across retries.
versionEnvelope schema version, currently 2.
createdOnUtcServer time when the event fired.
tenantNameCloud identifier. Use it when one endpoint serves multiple Clouds.
dataEvent-specific payload in camel case. Its fields depend on type.

Every webhook request includes an x-rev23-signature header. REV23 computes its HMAC-SHA256 digest from the raw request body and the subscription secret.

The header format is:

x-rev23-signature: sha256=<hex-digest>

Verify the signature before processing the event. Use the raw request body exactly as received; parsing and re-serializing the JSON changes the digest.

const crypto = require('crypto');
function isSignatureValid(rawBody, secret, signatureHeader) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(rawBody);
const expected = Buffer.from(`sha256=${hmac.digest('hex')}`);
const received = Buffer.from(signatureHeader ?? '');
return (
received.length === expected.length &&
crypto.timingSafeEqual(received, expected)
);
}

Webhook delivery is at least once. Your endpoint may receive the same event more than once, so store the envelope id and ignore repeats before performing work that cannot safely run twice.

RuleBehavior
AcknowledgmentAny 2xx response succeeds. Other responses count as failures.
TimeoutREV23 waits 30 seconds for a response.
RetriesREV23 makes up to 10 attempts for a failed event. Every attempt uses the same envelope id.
HTTP 410410 Gone deactivates the subscription immediately and is not retried.
Repeated failures15 consecutive failed attempts deactivate the subscription.
Custom headersREV23 includes the configured headers with every attempt.

Creating and managing subscriptions requires Webhooks → Subscribe. No built-in role includes it; the owner grants it deliberately. With Webhooks → Subscribe (All), that user’s subscriptions also receive events assigned to other users. See Roles & Permissions.