# Cosmic Notifications — webhooks for astrological events

Turn the AstroWay API from request-response into an **event stream**. Instead of polling the sky in a loop, you subscribe a URL to an event type — and AstroWay delivers a webhook the moment it occurs (signed with HMAC-SHA256, with auto-retry and auto-disable of dead subscriptions).

## Events (live)

These events are **mundane** (global sky state, independent of natal data) — every subscriber receives the same payload.

| Event | Register | Fires when |
|---|---|---|
| `retrograde-start` | `POST /v1/webhooks/retrograde-start` | a planet (Mercury–Pluto) stations retrograde |
| `retrograde-end` | `POST /v1/webhooks/retrograde-end` | a planet stations direct |
| `sign-ingress` | `POST /v1/webhooks/sign-ingress` | a planet (Sun + Mercury–Pluto) enters a new sign |
| `void-of-course-start` | `POST /v1/webhooks/void-of-course-start` | a void-of-course (VOC) Moon period begins |
| `eclipse-alert` | `POST /v1/webhooks/eclipse-alert` | 7 days before a solar or lunar eclipse |

<Aside type="note">
Natal-keyed events — `transit-trigger`, `return-due`, `dasha-change`, `mahadasha-end` — and the location-keyed `planetary-hour-tick` need each subscriber's natal data / coordinates and arrive in a later phase.
</Aside>

## How to subscribe

Requires an API key bound to your account.

```bash
curl -X POST https://api.astroway.info/v1/webhooks/retrograde-start \
  -H "X-Api-Key: aw_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://your-app.com/hooks/astroway" }'
# { "id": 44, "event": "retrograde-start",
#   "url": "https://your-app.com/hooks/astroway",
#   "signing_secret": "a1b2…",   ← store it; it verifies the signature
#   "active": true }
```

Manage subscriptions: `GET /v1/webhooks` (list), `GET /v1/webhooks/{id}`, `DELETE /v1/webhooks/{id}`, `POST /v1/webhooks/{id}/test` (test delivery to your URL).

## What lands on your URL

A `POST` with headers `X-AstroWay-Signature: sha256=<hmac>`, `X-AstroWay-Event`, `X-AstroWay-Delivery-Id` and body:

```json
{
  "event": "retrograde-start",
  "delivered_at": "2026-07-15T12:00:00.000Z",
  "subscription_id": 44,
  "data": {
    "planet": "Mercury",
    "station": "retrograde",
    "exactAt": "2026-07-15T11:48:09.967Z",
    "sign": "Leo",
    "longitude": 142.31
  }
}
```

## Verifying the signature

The signature is `HMAC-SHA256(signing_secret, raw_body)` in hex. Compare it to the `X-AstroWay-Signature` header (without the `sha256=` prefix):

```js

function verify(rawBody, header, secret) {
  const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
  const got = header.replace(/^sha256=/, '');
  return got.length === expected.length &&
    timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}
```

A subscription auto-disables after **5 consecutive failed deliveries** (non-2xx or an 8s timeout) — re-enable it via `GET /v1/webhooks`; pausing/resuming resets the counter.

## Pricing

Registering and managing subscriptions costs **Tier 1 (10 credits)** per call, made rarely. **Event delivery to your URL is not metered** — there is no separate tier.
