ClientoDocs
Pro

Outbound webhooks

Send real-time event notifications to any external URL.

Note

Outbound webhooks are available on the Pro plan only.

Overview

Outbound webhooks let Cliento notify any external URL when a key event occurs in your account — an invoice is paid, a milestone is validated, or a quote is accepted. This makes it easy to plug Cliento into Zapier, Make, or your own backend without polling.

Supported events

EventTrigger
invoice.paidAn invoice is marked as paid (Stripe, PayPal, or manual)
milestone.validatedA client validates a milestone from the portal
quote.acceptedA client accepts a quote from the portal
project.status_changedA project status changes

Setting up a webhook

  1. Go to Profile → Outbound webhooks.
  2. Click Add.
  3. Enter the destination URL (must be https://).
  4. Select one or more events to subscribe to.
  5. Click Create webhook.

Warning

Copy your signing secret immediately after creation — it is shown only once and cannot be recovered. If you lose it, delete the webhook and create a new one.

Payload format

Every request is an HTTP POST with a JSON body:

{
  "event": "invoice.paid",
  "createdAt": "2026-06-12T10:00:00.000Z",
  "data": {
    "invoiceId": "clx...",
    "invoiceNumber": "INV-0042",
    "clientId": "clx...",
    "paidVia": "stripe",
    "paidAt": "2026-06-12T10:00:00.000Z"
  }
}

The data object varies by event type but always includes the relevant entity IDs.

Verifying the signature

Every request includes an X-Cliento-Signature header:

X-Cliento-Signature: sha256=<hex-digest>

The digest is an HMAC-SHA256 of the raw request body signed with your webhook secret. Always verify it before processing:

import { createHmac } from "node:crypto";

function verifySignature(secret: string, rawBody: string, header: string): boolean {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  return expected === header;
}
import hmac, hashlib

def verify(secret: str, raw_body: bytes, header: str) -> bool:
    digest = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(digest, header)

Tip

Always use a constant-time comparison (like hmac.compare_digest) to prevent timing attacks.

Retries

If your endpoint returns a non-2xx status or times out (10 s), Cliento retries the delivery automatically:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry15 minutes

After 4 total attempts without success, the delivery is marked as failed and no further retries are made.

Tip

Make your endpoint idempotent — use the combination of event + data.invoiceId (or the relevant ID) as a deduplication key in case the same event is delivered more than once.

Managing webhooks

From Profile → Outbound webhooks you can:

  • Toggle a webhook on/off without deleting it.
  • Delete a webhook to permanently stop deliveries to that URL.

Up to 10 webhooks are allowed per account.

Zapier / Make integration

Point the webhook URL at a Zapier Catch Hook or a Make Custom webhook trigger. Use the event field as a filter to branch on different event types in your automation.

Compatible services

Outbound webhooks work with any service that accepts HTTP POST requests. Here are common integrations:

Notification & messaging

  • Slack — via Slack Incoming Webhooks or a Zapier/Make step. Post to a channel on every payment or milestone.
  • Discord — same pattern via Discord Incoming Webhooks. Useful if your team lives in Discord.
  • Telegram — trigger a bot message via the Telegram Bot API.

Automation platforms

  • Zapier — use a "Catch Hook" trigger, then connect to 6 000+ apps (Gmail, Notion, Airtable, HubSpot…).
  • Make (ex-Integromat) — "Custom webhook" trigger, more flexible for multi-step data transformation.
  • n8n — self-hosted alternative, "Webhook" node as trigger.

CRM & sales

  • HubSpot — move a deal to "Won" when a quote is accepted, or log a payment activity.
  • Pipedrive — update a deal stage or create an activity via the Pipedrive API.
  • Notion — add a row to a database (via Zapier/Make or the Notion API directly).

Accounting & finance

  • Google Sheets — append a row on each invoice.paid event for a lightweight payment ledger.
  • Airtable — same idea, with richer views and automations on top.
  • Pennylane / Qonto — via a custom backend that calls their API after receiving the event.

Custom backends

  • Any Express / FastAPI / Laravel endpoint. Verify the X-Cliento-Signature header and process the event however you need.
  • Supabase Edge Functions or Vercel Functions — serverless handlers that react to events without maintaining a server.

Tip

Zapier and Make are the fastest way to get started — no code required. For more control over data transformation or if you need to fan out to multiple services at once, a lightweight serverless function is worth the extra step.