Overview
The custom webhook destination forwards Ocean events to any HTTPS endpoint you control. Events are POSTed as batched JSON, and every request is signed with an HMAC-SHA256 signature so your receiver can verify it came from Ocean and was not tampered with. Use this destination when your SIEM, SOAR, or in-house pipeline isn’t covered by a dedicated vendor card but can accept inbound HTTPS POSTs — for example a serverless function, an HTTP collector, or an internal ingestion API. For an introduction to event types, payloads, and delivery semantics, see the SIEM Forwarding Overview.Prerequisites
Before configuring the destination in Ocean, prepare the receiving side:- An HTTPS endpoint that accepts
POSTrequests with a JSON body and returns a2xxstatus on success. - The endpoint must be reachable from the public internet so Ocean’s egress can reach it. If it sits behind a firewall or IP allowlist, allow Ocean’s egress IPs.
- A shared secret — a high-entropy random string you generate. Ocean uses it to sign each request; your receiver uses the same value to verify the signature.
Generate a strong secret (e.g.
openssl rand -hex 32) and store it securely. Ocean encrypts the secret and never displays it again once saved.Configure the destination in Ocean
Fill in the basics
| Field | Value |
|---|---|
| Name | A friendly name for this destination (e.g. SOC Ingest Prod). |
| URL | Your HTTPS endpoint, e.g. https://webhook.your-org.com/ocean/events. |
| Secret Value | The shared secret you generated. Required when creating the destination. |
(Optional) Customize the signature header
By default Ocean sends the signature in the
X-Ocean-Signature header. To use a different header name, set Signature header name. The value format is always sha256=<hex>.(Optional) Add custom headers
Under Custom headers, add any static headers your endpoint needs — for example an API gateway key or a tenant/environment tag. These are sent with every request.Header names follow the standard HTTP token format, and values cannot contain line breaks. You cannot use the reserved headers
X-Ocean-Signature, X-Ocean-Timestamp, X-Ocean-Delivery, or Content-Type.Pick events to forward
Under Events to forward, select at least one:
- Inbound Protection — malicious cases
- Inbound Protection — spam cases
- AI Response — report phishing
- AI Response — quarantine release
- Audit Logs
What Ocean sends
Each delivery is a singlePOST to your URL with a JSON body containing a batch of events.
Headers
| Header | Description |
|---|---|
Content-Type | Always application/json. |
X-Ocean-Signature | HMAC-SHA256 of the raw request body, hex-encoded, prefixed with sha256=. The header name is configurable. |
X-Ocean-Timestamp | Unix timestamp (seconds) when the request was sent. |
X-Ocean-Delivery | A unique UUID for this delivery attempt. Use it to deduplicate retries. |
| (your custom headers) | Any static headers you configured. |
Body
The body wraps one or more events in anevents array. Each entry carries delivery metadata plus the full Ocean event under event:
| Field | Type | Description |
|---|---|---|
event_id | string | Stable per-event ID — use it for deduplication. |
event_type | string | One of inbound_protection, report_phishing, quarantine_release, audit_log. |
event_time | number | Event time in Unix milliseconds. |
event | object | The full Ocean event payload. See the event payload reference. |
Batches contain one or more events. Always iterate the
events array rather than assuming a single entry.Verifying the signature
On each request, recompute the HMAC-SHA256 of the raw request body using your shared secret, hex-encode it, and compare it to the value in the signature header (after stripping thesha256= prefix). Use a constant-time comparison.
Verify against the exact bytes you received, before any JSON parsing or re-serialization. Re-encoding the body will change the signature.
Delivery & retries
- Events are forwarded near real time in small batches.
- Your endpoint must return a
2xxstatus to acknowledge receipt. - A failed batch is retried automatically. Ocean only advances once a batch is acknowledged, so no events are dropped — your receiver should be idempotent and deduplicate using
event_id(orX-Ocean-Delivery). - Retries use exponential backoff.
5xx,408,429, and network/timeout errors are retried; other4xxresponses are treated as permanent failures and are not retried.
Advanced
Skip TLS verification
Under Advanced, you can enable Skip TLS verification to disable certificate validation. This is intended only for testing against endpoints with self-signed certificates.Troubleshooting
| Symptom | Likely cause | Resolution |
|---|---|---|
| Destination shows Endpoint unreachable | URL is wrong or not reachable from the public internet. | Verify the URL and that the endpoint accepts external HTTPS traffic. |
| Signature never matches | Body re-encoded before verifying, or wrong secret. | Verify against the raw bytes, before parsing. Confirm the secret matches what you entered in the Portal. |
| Destination shows Authentication / Permission denied | Your endpoint returned a 4xx rejecting the request. | Check your endpoint’s auth (custom headers / API key) and that it accepts the request format. |
| Destination shows Rate limited | Your endpoint returned 429. | No action required — Ocean retries automatically. Raise your endpoint’s rate limit if it persists. |
| Duplicate events | A retry re-delivered an acknowledged batch. | Deduplicate using event_id. |
| No events yet | First export is still pending. | Wait a few minutes after creating the destination. |
Security
- The shared secret is stored encrypted and is never displayed once saved.
- All traffic to your endpoint uses TLS.
- Every request is signed with HMAC-SHA256 — always verify the signature before trusting an event.
