FATHOM

A deep-dive into all things ORCA.
From core concepts to advanced settings.

Advanced Settings

Webhooks

Webhooks are the ORCA API in reverse. The API lets your systems ask ORCA questions; a webhook means ORCA calls you the moment something changes, with no polling and no waiting. New contact created? Lead status updated? To-do completed? ORCA sends a signed POST to any URL you choose, usually within a couple of seconds.

If you want ORCA talking to Zapier, a data warehouse, a Slack notifier, or anything you have built yourself, this is the mechanism.


Creating a webhook

Head to Settings → Webhooks. You will need the settings permission on your account.

  1. Give it a name that describes the tool on the other end, like "Zapier: new leads".
  2. Enter the URL to send to. It must be https.
  3. Tick the events it should receive (see the list below).
  4. Optionally pick a section. This limits record events to that one section, so a webhook can listen for new Leads without hearing about every Job and Deal too. Other event types ignore the section.
  5. Click Add webhook and copy the signing secret straight away. Like an API key, it is shown exactly once.

The events

Events are named resource.action:

ResourceEvents
Contactscontact.created, contact.updated, contact.deleted
Companiescompany.created, company.updated, company.deleted
Recordsrecord.created, record.updated, record.deleted
To-Dostodo.created, todo.updated, todo.deleted
Calendar Eventsevent.created, event.updated, event.deleted

Events fire however the change happens: someone working in ORCA, a write through the API, or an automation. Bulk imports are the deliberate exception, so importing ten thousand contacts will not send ten thousand POSTs to your endpoint.

What arrives

Each delivery is a JSON POST:

{
  "id": 42,
  "event": "contact.created",
  "occurred_at": "2026-07-16T15:04:05Z",
  "data": {
    "id": 648930,
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com"
  }
}

The data block is the same shape the API returns for that resource, so code that reads GET /v1/contacts/{id} responses can read webhook payloads unchanged. Deleted events carry just the id (plus the section, for records).

Three headers ride along: X-Orca-Event (the event name), X-Orca-Delivery (the delivery id), and X-Orca-Signature (see below).

Verifying the signature

Every delivery is signed with your webhook's secret, so your endpoint can be certain the request came from ORCA and not from someone who found the URL. The header looks like:

X-Orca-Signature: t=1784216645,v1=5257a869e7...

To verify: concatenate the timestamp, a dot, and the raw request body, compute an HMAC SHA-256 with your secret, and compare it to v1. In PHP:

[$t, $v1] = explode(',', $request->header('X-Orca-Signature'));
$t  = substr($t, 2);   // strip "t="
$v1 = substr($v1, 3);  // strip "v1="

$expected = hash_hmac('sha256', $t . '.' . $request->getContent(), $secret);

$valid = hash_equals($expected, $v1) && abs(time() - (int) $t) < 300;

The timestamp check (five minutes is a sensible tolerance) stops an intercepted request being replayed later. If you skip verification your integration will still work, but anyone who discovers your endpoint URL could feed it fake events. Verify.

Retries and the delivery log

Your endpoint should return a 2xx status quickly; anything else counts as a failure. Failed deliveries are retried five more times over roughly eleven hours, with growing gaps between attempts. If a webhook fails 25 deliveries in a row it is switched off automatically, so a dead endpoint cannot queue work forever. Re-enable it from the Webhooks list once the endpoint is healthy; a single successful delivery resets the count.

Every webhook has a delivery log: click its name in Settings → Webhooks to see recent deliveries with their status, response code, and attempt count. It keeps 30 days of history and is the first place to look when a delivery has not arrived.

Managing webhooks through the API

Everything above can also be done programmatically, which is how tools like Zapier subscribe and unsubscribe on their own:

curl -X POST https://api.orca-crm.com/v1/webhooks \
  -H "Authorization: Bearer orca_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/orca", "events": ["contact.created"]}'

The key needs the webhooks:manage scope. The creation response includes the signing secret, once. The full reference lives at api.orca-crm.com/docs.

Good to know

  • Webhook URLs must be https. ORCA will not post your data over plain http.
  • One change produces one event, even if a record save touched a dozen fields at once.
  • Deliveries are per webhook: two webhooks listening for the same event each get their own copy, with their own signature.
  • Deleting a webhook stops deliveries immediately. The delivery history is kept.
  • A handy way to see it all working: create a free test URL at webhook.site, point a webhook at it, and change something in ORCA.

If you get stuck, email support@orca-crm.com and we will point you the right way.

Previous
Using the ORCA API