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_id and design_id from an Aurora webhook URL?
  • How do I handle project_created, design_created or performance_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 use X-Aurora-Webhook-Token; the examples read the name from AURORA_SOLAR_WEBHOOK_HEADER (default X-Aurora-Webhook-Token).
  • The expected value is AURORA_SOLAR_WEBHOOK_SECRET: the exact, whole header_auth_value, including any Bearer prefix 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_digest on bytes (encode both sides; str raises 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_created&project_id=3fa8...&source=api. 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:

EventSent When
project_createdA project is created (project_id, source, order_id)
project_changedProject attributes change (project_id, source, attributes)
project_status_changedProject status changes (project_id, status; any string)
design_createdA design is created (project_id, design_id, source)
performance_simulation_job_completedA performance simulation finishes (design_id, job_id, status, source)
agreement_status_changedAn agreement is sent, signed, canceled, etc.
web_proposal_viewedA 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


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 10, 2026

View on GitHub →