---
title: "Test Company Webhook"
method: POST
path: "/companies/{companyId}/webhook/test"
tags: ["Company Management"]
---

# Test Company Webhook

`POST /companies/{companyId}/webhook/test`

## Request

- Base URL: `https://api.hudsonrock.com/json/v3`
- URL: `https://api.hudsonrock.com/json/v3/companies/{companyId}/webhook/test`
- Auth: API key in header `api-key`
- TypeScript: <https://skmtc.dev/hudsonrock/apis/cavalier-api/docs/companies/:companyId/webhook/test/post.ts> (a function with typed inputs; its response is checked against the schema)

Send a single test event to a company webhook so you can validate your receiver before going live.

The request is delivered exactly like a real one: HTTPS `POST`, `Content-Type: application/json`, the same `{"event": {...}, "sourcetype": "..."}` envelope, and your token sent as entered in the `auth_header` header. Use it to confirm authentication, body parsing, index or sourcetype routing, and any parsing of the MongoDB Extended JSON fields.

- **Event type:** by default the test matches the webhook's current mode: a `hudsonrock:data` event when `data_alert` is `true`, otherwise a `hudsonrock:alert` event. Pass `type` to test the other format.
- **Test marker:** every test event carries `"test": true` inside `event`. Real events never include this field, so you can drop test events from production rules and playbooks.
- **Content:** test events contain placeholder data only. Summary alerts list the company's monitored domains with zero counts. Data alerts contain one anonymized `employee` record built around the company's first domain, with `TEST-` placeholder values for secrets.
- **Unsaved configuration:** pass `webhook` in the body to test a URL, token and header before saving them. Otherwise the company's stored webhook is used; if there is none, `409 Conflict` is returned.
- **Result:** the response reports whether your endpoint returned a 2xx (`delivered`), the HTTP status, the response time, the first 1 KB of the response body, and the exact payload we sent. A rejected or unreachable endpoint still returns `200` from this API, with `delivered: false`.
- **Limits:** the test makes one attempt with a 10-second timeout and doesn't follow redirects. Destinations that resolve to private, loopback or link-local addresses are refused. You can send one test per company every 10 seconds; more frequent calls return `429`.

If the authenticated user belongs to an organization with `synced_data: true`, only the user with `organization.role: "owner"` can call this endpoint. Other members receive `403 Forbidden`.

## Path parameters

- `companyId` string, required

## Request body

- object
  - `type` 'alert' | 'data': `alert` sends a `hudsonrock:alert` summary event, `data` sends a `hudsonrock:data` event. Defaults to the webhook's current mode (`data` when `data_alert` is true).
  - `webhook` object: Optional webhook configuration to test instead of the stored one. It isn't saved. `url` and `token` are required when provided.
    - `url` string, uri, required: HTTPS URL to receive webhook notifications.
    - `token` string, required: Token sent with each webhook request to authenticate it (e.g. a Splunk HEC token or bearer token).
    - `auth_header` string: Name of the HTTP header used to send the token. Defaults to "Authorization" if not specified.

## Response `200`

The test event was sent (or attempted). Check `delivered` for the outcome.

- object
  - `delivered` boolean: True when your endpoint responded with a 2xx status.
  - `status_code` integer, nullable: HTTP status returned by your endpoint. Null if no response was received.
  - `response_time_ms` integer, nullable: Time from sending the request until your endpoint responded, in milliseconds.
  - `response_body` string, nullable: First 1 KB of your endpoint's response body, for debugging.
  - `error` string, nullable: Why no response was received, e.g. a DNS, TLS or connection error, a timeout, or a refused destination. Null when your endpoint responded.
  - `type` 'alert' | 'data': Which event format was sent.
  - `payload` union: The exact JSON body that was sent.
    - WebhookAlertEvent: Standard summary alert (`data_alert: false`). One event per company per notification run, with counts per monitored domain and no credentials.
      - `event` object: Keyed by company name. Each company maps every monitored domain (including domains with zero counts) to its counters: `employees`, `third_party`, `externals`, `clients`, `apps`, `supply_chain`.
        - `earliest_timestamp` integer: Unix time when the earliest record in this batch was ingested. This is not the compromise date.
        - `test` boolean: Present and `true` only on test events sent through `POST /companies/{companyId}/webhook/test`. Never present on real events.
      - `sourcetype` 'hudsonrock:alert'
    - WebhookDataEvent: Data alert (`data_alert: true`). One event per compromised machine per match category, containing the full record for that machine. Dates and IDs use MongoDB Extended JSON (`{"$date": "<ISO-8601>"}`, `{"$oid": "<id>"}`).
      - `event` object
        - `category` 'employee' | 'third_party' | 'client' | 'app' | 'external': Match category. A machine that matches more than one category produces one event per category.
        - `stealer` object: The compromised machine record. `data.credentials` contains only the credentials that matched this company's assets in this category. Employee and third_party events also carry full machine context (IP, OS, computer name, malware path, antivirus, local time, installed software, cookie insights, `employeeAt`/`clientAt`); client, app and external events carry IP, OS, computer name, antivirus and malware path only. No data is masked.
        - `test` boolean: Present and `true` only on test events sent through `POST /companies/{companyId}/webhook/test`. Never present on real events.
      - `sourcetype` 'hudsonrock:data'

## Other responses

- `400`: Validation error - the request or request body was invalid
- `401`: Unauthorized - the server could not authenticate the request
- `403`: Forbidden - the server authenticated the request but refuses to process it because of insufficient permissions
- `404`: Not found - the server could not find the requested resource
- `409`: Conflict - the request conflicts with the current state of the resource
- `429`: Rate limit exceeded - the server has received too many requests in a short period of time
- `500`: Internal server error - the server encountered an unexpected condition that prevented it from fulfilling the request

## Changes

- **2026-11-03** `a7ebb4dfd47f`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/hudsonrock/apis/cavalier-api/changes/companies/:companyId/webhook/test/post.md)

---

[API](https://skmtc.dev/hudsonrock/apis/cavalier-api.md) - [All operations](https://skmtc.dev/hudsonrock/apis/cavalier-api/llms.txt) - [OpenAPI document](https://skmtc.dev/hudsonrock/apis/cavalier-api/revisions/a7ebb4dfd47f?raw)
