---
title: "Create Subscription"
method: POST
path: "/v1/alerts/subscriptions"
tags: ["alerts"]
---

# Create Subscription

`POST /v1/alerts/subscriptions`

## Request

- Base URL: `https://api.ctindex.io`
- URL: `https://api.ctindex.io/v1/alerts/subscriptions`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Create a new domain-watch alert subscription for the authenticated key.

Tier-aware:
  * Free-tier keys may only set ``email`` — ``webhook_url`` is rejected
    with 403 ``webhook_requires_paid_tier``.
  * Subscription count must remain below the caller's tier cap defined in
    ``TIER_LIMITS[<tier>]['alert_subscriptions']``. Exceeding it returns
    403 ``alert_quota_exceeded``.

## Cookies

- `ctix_session` string, nullable

## Request body

- AlertSubscriptionCreate: Request body for POST /v1/alerts/subscriptions. Tier-aware behaviour enforced server-side: * Free-tier keys may only set ``email`` — supplying ``webhook_url`` returns HTTP 403 ``webhook_requires_paid_tier``. * Each tier has a maximum number of concurrent subscriptions; exceeding the cap returns HTTP 403 ``alert_quota_exceeded``. Two watch styles (task #502): * ``match_type='exact'`` (default) — the legacy apex watch. ``domain`` is the watched apex; every cert at or under it fires. * ``match_type='keyword'`` — a brand-token watch matched via the permutation/confusable engine over the CT firehose. ``keyword`` is required; ``edit_distance`` / ``homoglyphs`` / ``combosquat`` / ``tld_set`` tune the fuzziness.
  - `domain` string, required
  - `webhook_url` string, nullable
  - `email` string, nullable
  - `destination_type` string
  - `destination_config` object, nullable
  - `enrichment_enabled` boolean
  - `match_type` string
  - `keyword` string, nullable
  - `edit_distance` integer
  - `homoglyphs` boolean
  - `combosquat` boolean
  - `tld_set` string[], nullable

## Response `201`

Successful Response

- AlertSubscriptionCreatedResponse: Response for ``POST /v1/alerts/subscriptions``. Identical to ``AlertSubscriptionResponse`` plus a one-shot ``signing_secret`` field carrying the plaintext HMAC signing key (task #76). The secret is returned **exactly once** at create time and is never re-exposed by any read endpoint — store it in a secret manager immediately.
  - `id` string, uuid, required
  - `domain` string, required
  - `webhook_url` string, nullable
  - `email` string, nullable
  - `destination_type` string
  - `destination_config` object, nullable
  - `enrichment_enabled` boolean
  - `match_type` string
  - `keyword` string, nullable
  - `edit_distance` integer
  - `homoglyphs` boolean
  - `combosquat` boolean
  - `tld_set` string[], nullable
  - `last_event_at` string, date-time, nullable
  - `last_event_delivered` boolean, nullable
  - `event_count` integer
  - `created_at` string, date-time, nullable
  - `signing_secret` string, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/ctindex/apis/certindex-api.md) · [All operations](https://skmtc.dev/ctindex/apis/certindex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ctindex/apis/certindex-api/revisions/d5bc0ec85bc9?raw)
