Skip to content

Identified Accounts Webhook

Send every company Rose identifies visiting your site to your own endpoint — the moment it's identified. Wire those accounts straight into your CRM, n8n, Zapier, or any HTTPS endpoint and build your own follow-up: alert a rep, create a lead, enrich further, or drop a row in your warehouse.

This is self-serve — you set it up yourself on the Integrations page, no account manager needed.

How it works

When Rose identifies a company behind a visit (via IP / company enrichment), it sends a single POST to your webhook URL with that account's details as JSON. One request per newly identified account — Rose de-duplicates upstream, so a returning visitor already identified doesn't fire again.

Delivery is best-effort and fully in the background: if your endpoint is slow or down, your visitors' experience is never affected. Rose retries a few times (with backoff) and then gives up for that account.

De-duplication is best-effort, so on rare occasions the same account can arrive twice. Every payload carries a stable event_id — de-duplicate on it and ignore any repeat you've already processed.

What you need

  • An HTTPS endpoint that accepts a POST with a JSON body (a Zapier "Catch Hook", an n8n Webhook node, or your own API route).
  • Access to the Rose backoffice Integrations page for your site.

Set it up

  1. In the Rose backoffice, open Integrations and find the Identified accounts webhook card (under Webhooks).
  2. Turn Enable webhook on, then click Configure and fill in:
Setting What to enter
Webhook URL The HTTPS address that receives each identified account. Example: https://hooks.zapier.com/hooks/catch/123/abc.
Secret key (optional) A secret you choose so your endpoint can confirm the request really came from Rose. Leave empty to skip. See Verifying the signature.
  1. Click Save. The next company identified on your site is posted to your endpoint.

The payload

Rose sends a JSON body like this:

{
  "event_type": "account_identified",
  "event_id": "9f2c1a...e3b7",
  "timestamp": "2026-07-06T14:32:10.123456+00:00",
  "site_name": "yourdomain.com",
  "person_id": "0191f2a4-...",
  "account": {
    "company_name": "Acme Inc",
    "domain": "acme.com",
    "company_description": "B2B logistics software",
    "sector": "Software",
    "sub_sector": "Supply chain",
    "company_linkedin_url": "https://www.linkedin.com/company/acme",
    "location": "Boston, MA",
    "employee_count": "51-200",
    "country": "US"
  },
  "person": {
    "job_title": "VP Sales",
    "linkedin_url": "https://www.linkedin.com/in/jane-doe",
    "email": "jane@acme.com"
  },
  "enrichment": {
    "source": "enrich_so",
    "tier": "enrich_so_api",
    "enriched_at": "2026-07-06T14:32:10+00:00"
  }
}
Field Description
event_type Always account_identified.
event_id Stable id for one identified account. Use it to de-duplicate: if you receive two requests with the same event_id, treat them as the same account and ignore the repeat.
timestamp When Rose sent the webhook (ISO 8601, UTC).
site_name Your site domain.
person_id Rose's anonymous visitor id, when known (may be null).
account The identified company. Any field Rose couldn't determine is null.
person Person-level details when the source provides them (often null for company-only identification).
enrichment Which source identified the account and when.

Some fields depend on what the enrichment source returns — expect null for anything unavailable for a given account. Always code your endpoint to tolerate missing fields.

Verifying the signature

If you set a Secret key, Rose adds an X-Webhook-Signature header to every request: a hex-encoded HMAC-SHA256 of the raw request body, keyed with your secret. Recompute it on your side and compare to confirm the request is genuine.

Node.js example:

const crypto = require('crypto');

function isFromRose(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody) // the exact raw bytes, before JSON parsing
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}

Sign over the raw body bytes exactly as received — parsing and re-serializing the JSON can change the bytes and break the check.

Troubleshooting

Nothing arrives at your endpoint Likely cause / fix
No requests at all Check Enable webhook is on and Save was clicked, and that the Webhook URL starts with https://.
Requests but company data looks empty Rose only fires once a company is actually identified. Fields the source couldn't resolve come through as null.
Signature never matches Recompute HMAC over the raw body, not the re-serialized JSON, and confirm the secret matches exactly.
A known visitor didn't fire Rose de-duplicates already-identified accounts — a returning identified visitor won't re-fire.