> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Webhook Endpoint

> Register an account-level HTTPS endpoint to receive signed webhook events.

Registers an HTTPS endpoint to receive [signed](/api-reference/v2/webhooks/signing) events. An account may have up to **20** endpoints. The response includes the **signing secret** — returned here (and on [rotation](/api-reference/v2/webhooks/rotate-secret)) — which you store to [verify signatures](/api-reference/v2/webhooks/signing).

<Note>
  These are the **partner webhook control plane** endpoints (HMAC-signed, retried, replayable). They are distinct from the per-list [Delivery Forwarding webhooks](/api-reference/v2/webhooks/events) configured in the dashboard.
</Note>

## Body Parameters

<ParamField body="url" type="string" required>
  An `https://` URL, max 2000 characters, resolving to a public host (private/loopback addresses are rejected).
</ParamField>

<ParamField body="events" type="array" required>
  A non-empty list of event types to subscribe to — any of the message events (`message.delivered`, `message.failed`, `message.reply`, `contact.opted_out`) or business-profile events (`business_profile.verified`, `business_profile.rejected`, `business_profile.name_confirm_required`, `business_profile.review_required`).
</ParamField>

## Examples

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.tracklysms.com/api/v2/webhooks \
    -H "X-Api-Key: trk_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{ "url": "https://hooks.bizinga.com/trackly", "events": ["message.delivered", "message.failed"] }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://api.tracklysms.com/api/v2/webhooks",
      headers={"X-Api-Key": "trk_your_api_key"},
      json={"url": "https://hooks.bizinga.com/trackly", "events": ["message.delivered", "message.failed"]},
  )
  print(resp.json()["signingSecret"])  # store this
  ```
</RequestExample>

<ResponseExample>
  ```json 201 — Created theme={null}
  {
    "id": "66b0f7c84a1d4b2e9c3a1f2e",
    "accountId": 1042,
    "url": "https://hooks.bizinga.com/trackly",
    "events": ["message.delivered", "message.failed"],
    "active": true,
    "signingSecretRotatedAt": null,
    "createdAt": "2026-07-26T14:03:11Z",
    "updatedAt": "2026-07-26T14:03:11Z",
    "signingSecret": "9f2c...64hex",
    "previousSigningSecret": null
  }
  ```
</ResponseExample>

## Error Codes

| HTTP Status | Error Code          | Description                           |
| ----------- | ------------------- | ------------------------------------- |
| 400         | `validation_failed` | The URL or events list is invalid.    |
| 409         | `quota_exceeded`    | The account already has 20 endpoints. |

## Next Steps

<CardGroup cols={2}>
  <Card title="Verify signatures" icon="shield-check" href="/api-reference/v2/webhooks/signing">
    Validate the HMAC on every event.
  </Card>

  <Card title="List endpoints" icon="list" href="/api-reference/v2/webhooks/list-endpoints">
    See all endpoints on the account.
  </Card>
</CardGroup>
