Creator Notify v1.0.0

Your API keys

Every account gets two keys. They are not interchangeable: one is safe to publish in your HTML, the other must never leave your server.

Create an account

Open /register and fill in three required fields, then press Create account & generate keys. The keys are shown once — copy both before you close the page.

FieldRequiredExampleNotes
nameyesMy Blog2–120 characters. Your name or the site's name; never shown to visitors.
contact_emailyesyou@example.comThe only way an operator can reach you about the site. Stored, never published by any endpoint.
originyeshttps://example.comScheme + host + optional port. No path, query or credentials. Stored lower-cased.

The same thing from a terminal, using the registration endpoint directly:

curl -X POST https://YOUR-API-HOST/v1/sites/register \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "My Blog",
    "contact_email": "you@example.com",
    "origin": "https://example.com"
  }'
{
  "success": true,
  "site": {
    "id": "site_9f2c1a...",
    "name": "My Blog",
    "origin": "https://example.com",
    "public_identifier": "pub_8d1f0c...",
    "status": "active",
    "expires_at": "2026-02-07T12:00:00.000Z",
    "inactivity_days": 7
  },
  "credentials": {
    "public_identifier": "pub_8d1f0c...",
    "api_key": "cn_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "api_key_note": "Store this key in a server-side secret store. It cannot be retrieved again; rotate it if it is lost."
  }
}

One website, one account, two keys

An account is a website. Registering the same address twice is refused with DUPLICATE_SITE (409) — the credentials already exist, and there is no "create another account" step. If you lost the secret key, rotate it or use the one from your secret store; do not register again.

Repeated attempts block the website permanently

Every registration request for the same address is counted, whatever its outcome. Once the count passes REGISTRATION_ATTEMPT_LIMIT (4 by default), that website is blocked permanently: registration, publishing and reads all return SITE_BLOCKED (403), and expiry, reactivation or rotating a key cannot lift it. Only an operator can unblock it.

AttemptResult
1201 — account created, two keys returned once
2 – 4409 DUPLICATE_SITE, with attempts and attempts_remaining in details
5 and later403 SITE_BLOCKED — permanent; the account's existing keys stop working too

Use one account per website. If you run several sites, create several accounts — each one gets its own pair of keys, its own subscriber list and its own rate-limit budget.

The two keys, side by side

Public keySecret key
Looks likepub_8d1f0c…cn_live_XXXXXXXXXXXXXXXXXXXXXXXX
Where it livesYour website's HTML or JS bundleYour server's environment / secret store
Can collect subscriptionsYes — that is all it doesYes
Can send notificationsNeverYes
Can read subscriber dataNoCounts and metadata only, never endpoints
If it leaksNothing: it only identifies your site to a visitor's browserAnyone could send notifications as you — rotate immediately

The public key is not a "lesser secret key"

Sending always requires the secret key, and the secret key never authorises a browser to do anything a browser cannot already do. There is no code path where a public key, an Origin header or a website id from a request body can be promoted into an authenticated identity: the tenant is derived from the hash of the presented secret key, and nothing else.

Storing the secret key

# server environment, one of many options
CREATOR_NOTIFY_URL=https://YOUR-API-HOST
CREATOR_NOTIFY_KEY=cn_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • Never in HTML, a JavaScript bundle, localStorage, sessionStorage, a cookie, or a repository.
  • Never in client-side analytics, error trackers or chat messages.
  • One key per environment is fine, but a separate account per site is cleaner: subscriptions, counts and rate limits are all per account.

Check your account

curl https://YOUR-API-HOST/v1/sites/status \
  -H "Authorization: Bearer $CREATOR_NOTIFY_KEY"

The response includes expires_at, expires_in_seconds, api_key_prefix, key_version and notification_count. It never includes the key itself or any subscriber endpoint.

Rotate or revoke

ActionEndpointEffect
RotatePOST /v1/sites/rotate-keyReturns a new secret key and invalidates the old one immediately. Subscribers, notifications and the registration stay intact.
RevokePOST /v1/sites/revoke-keySuspends the registration. Every authenticated call returns SITE_SUSPENDED until it is reactivated.
ReactivatePOST /v1/sites/reactivateClears an expired or suspended state and restarts the inactivity window.
curl -X POST https://YOUR-API-HOST/v1/sites/rotate-key \
  -H "Authorization: Bearer $CREATOR_NOTIFY_KEY"

The inactivity rule

A registration stays active while it publishes. If it does not send a notification for the configured window (seven days by default), it lapses: publishing returns SITE_EXPIRED until you call POST /v1/sites/reactivate. Your subscriber list is never deleted by expiry — expiry is about whether the account may send, retention is a separate setting.

  • Only a successful publish refreshes the timer.
  • Reading your status, subscribing, health checks, documentation views and failed requests never refresh it.
  • Expiry is enforced when the request is handled, and again by a background sweep, so the two can never disagree about an expired account.

Restricted deployments

If the service operator has set a registration token, the registration form asks for it under Registration token and the API expects the same value in an x-registration-token header. Without it, POST /v1/sites/register returns INVALID_API_KEY.

Next