---
title: "Create webhook endpoint"
method: POST
path: "/api/v1/webhooks"
tags: ["Webhooks"]
---

# Create webhook endpoint

`POST /api/v1/webhooks`

## Request

- Base URL: `https://earningsfeed.com`
- URL: `https://earningsfeed.com/api/v1/webhooks`
- Auth: HTTP bearer

Register a URL to receive webhook notifications when new SEC filings match your alert preferences.

## How It Works

1. Create a webhook endpoint with your URL
2. Configure alert preferences on your watchlist (form types, frequency)
3. When a matching filing is ingested, a signed POST request is sent to your URL

## Signing Secret

The response includes a `signingSecret` — **save it immediately**. It is only returned once at creation time and cannot be retrieved later. Use it to verify that incoming webhooks are authentic.

## Payload Format

Webhook payloads are JSON matching the **WebhookEventPayload** schema. The `data` field uses the same filing shape as items returned by `GET /api/v1/filings` (the **FeedFiling** schema).

## Signature Verification

Each delivery includes two headers for verification:
- `X-EarningsFeed-Signature`: `sha256=<hex>`
- `X-EarningsFeed-Timestamp`: Unix seconds

To verify, compute `HMAC-SHA256(signingSecret, "{timestamp}.{body}")` and compare to the signature hex. Example in Node.js:

```javascript
const crypto = require("crypto");
const expected = crypto
  .createHmac("sha256", signingSecret)
  .update(`${timestamp}.${rawBody}`)
  .digest("hex");
const actual = signature.replace("sha256=", "");
if (actual !== expected) throw new Error("Invalid signature");
```

## Auto-Disable

Endpoints are automatically disabled after 10 consecutive delivery failures. A successful delivery resets the failure counter.

## Request body

- object
  - `url` string, uri, required: The URL to deliver webhook events to (must be HTTPS or HTTP)
  - `description` string: Human-readable description of this webhook
  - `source` string: Identifier for the integration source (e.g., 'manual', 'zapier', 'make')

## Response `200`

Webhook endpoint created (includes signing secret)

- object
  - `id` number, required
  - `url` string, required
  - `enabled` boolean, required
  - `description` string, nullable, required
  - `source` string, required
  - `failureCount` number, required
  - `lastDeliveredAt` string, nullable, required
  - `disabledAt` string, nullable, required
  - `createdAt` string, required
  - `signingSecret` string, required: The signing secret for verifying webhook payloads (only shown on creation)

## Other responses

- `400`: Invalid request body
- `401`: Unauthorized - API key required
- `429`: Minute rate limit or tier monthly quota exceeded. Retry-After points to the relevant minute or monthly reset.
- `500`: Internal server error

---

[API](https://skmtc.dev/earningsfeed/apis/earnings-feed-api.md) · [All operations](https://skmtc.dev/earningsfeed/apis/earnings-feed-api/llms.txt) · [OpenAPI document](https://skmtc.dev/earningsfeed/apis/earnings-feed-api/revisions/feefa3647c61?raw)
