Agent skill
Aurora Solar Webhooks Skill
Receive and authenticate Aurora Solar webhooks. Use when setting up an Aurora Solar webhook endpoint, checking the header_auth_key token header, reading event data from the query string of GET requests, debugging 401s, or handling events like project_created, design_created, project_status_changed and performance_simulation_job_completed.
Install this skill
npx skills add hookdeck/webhook-skills --skill aurora-solar-webhooks
Aurora Solar (solar design software) fires a webhook when something happens in your tenant: a project or design is created, a job finishes, an agreement changes status. Each webhook is a GET request with no body. The event data (identifiers and statuses) arrives in the query string, built from a URL template you provide. Webhooks are not signed, so your endpoint authenticates them with a secret header you add to the subscription.
Set header_auth_key and header_auth_value on the Aurora Solar webhook and enter them here. Webhooks without them send nothing to verify.
When to Use This Skill
- How do I receive Aurora Solar webhooks?
- How do I authenticate Aurora Solar webhooks (
header_auth_key/header_auth_value)? - Does Aurora Solar sign webhook payloads? (No: use a secret header)
- How do I read
project_idanddesign_idfrom an Aurora webhook URL? - How do I handle
project_created,design_createdorperformance_?simulation_ job_ completed - Why does my Aurora Solar webhook endpoint return 401?
Verification (core)
const crypto = require('crypto');
// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
const ha = crypto.createHash('sha256').update(String(a)).digest();
const hb = crypto.createHash('sha256').update(String(b)).digest();
return crypto.timingSafeEqual(ha, hb);
}
function verifyAuroraSolarRequest(
headers,
secret = process.env.AURORA_SOLAR_WEBHOOK_SECRET,
headerName = process.env.AURORA_SOLAR_WEBHOOK_HEADER || 'X-Aurora-Webhook-Token'
) {
if (!secret) return false; // never accept when unconfigured
const received = headers[headerName.toLowerCase()]; // Node lowercases header names
return Boolean(received) && safeEqual(received, secret); // whole value, no Bearer parsing
}
- The header name is user-chosen (
header_auth_key). Aurora's docs useX-Aurora-Webhook-Token; the examples read the name fromAURORA_(defaultSOLAR_ WEBHOOK_ HEADER X-Aurora-Webhook-Token). - The expected value is
AURORA_: the exact, wholeSOLAR_ WEBHOOK_ SECRET header_auth_value, including anyBearerprefix you typed. Look the header up case-insensitively and compare the whole value; do not strip or parse a prefix. - Check the header first, then read the query parameters. Missing header or mismatch:
401. - Python:
hmac.compare_digeston bytes (encode both sides;strraises on non-ASCII). - Read any body raw (
express.raw({ type: '*/*' })); Aurora sends none, but a proxy might.
A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use an HTTPS URL, and rotate the header value on the subscription if it leaks. Aurora also offers Basic Auth; Hookdeck's Aurora Solar source does not cover it, so use header-based token authentication.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Webhook URL Template
Aurora fires GET requests to a URL generated from a template you provide when creating the subscription (url_template). Placeholders are upper-case attribute names in angle brackets. Each subscription is for one event, so put a static event parameter in the template and dispatch on it:
https://<hookdeck-url>?event=project_created&project_id=<PROJECT_ID>&source=<SOURCE>
Aurora fills in the attributes, so the request looks like GET /?event=project_. Hookdeck's Aurora Solar source pre-selects GET without managing the method; the receivers also accept POST for flexibility. Respond within 10 seconds; failures (timeout, 3xx/4xx/5xx) are retried 5 more times over 24 hours.
Event Types
The event is the subscription's event (the docs list 32). Common ones:
| Event | Sent When |
|---|---|
project_created | A project is created (project_id, source, order_id) |
project_changed | Project attributes change (project_id, source, attributes) |
project_status_changed | Project status changes (project_id, status; any string) |
design_created | A design is created (project_id, design_id, source) |
performance_ | A performance simulation finishes (design_id, job_id, status, source) |
agreement_status_changed | An agreement is sent, signed, canceled, etc. |
web_proposal_viewed | A web proposal is viewed (design_id, project_id, is_first_view) |
See references/overview.md for all 32 events and their attributes.
Environment Variables
AURORA_SOLAR_WEBHOOK_HEADER=X-Aurora-Webhook-Token # your header_auth_key
AURORA_SOLAR_WEBHOOK_SECRET=your-header-auth-value # your exact, whole header_auth_value
Local Development
Aurora can't reach localhost. Tunnel with the Hookdeck CLI (no account required):
npx hookdeck-cli listen 3000 aurora-solar --path /webhooks/aurora-solar
Use the printed URL (with your ?event=... template) as the webhook URL in Aurora.
Resources
- references/overview.md - What Aurora Solar webhooks are, events and URL attributes
- references/setup.md - Create a subscription with header-based token authentication
- references/verification.md - Header check details, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests