Webhook alert setup
Receive signed permit alerts in your own HTTPS application.
In your account, select Webhook, enter a public HTTPS URL, generate a signing key, copy it into your receiving app, and save preferences. Keep the key private; saved keys are not displayed again.
Request format
Permit Leads sends a JSON POST. Each body includes event_id, type (permit.new or permits.digest), generated_at, frequency, and a permits array. Permit fields include source ID, city, canonical permit category (trade), address, ZIP, issue date, published valuation, contractor name when available, lead note, source_status, source_milestone, source_completed_at, roof_scope, structure_scope, solar_suitability (unverified) and an optional applicant. applicant is set only for Minneapolis permits whose city record lists a company applicant that is not the property owner; it is null for every other permit and city, and it never means contractor of record. Missing source fields remain null. Source completion timestamps do not confirm completed roof work. Scope-rule confidence is not solar suitability.
Verify every request
Read X-Permit-Leads-Timestamp and the raw request body. Compute HMAC-SHA256 with your signing key over timestamp + "." + raw_body. Compare the hex digest to X-Permit-Leads-Signature, which starts with sha256=, using a constant-time comparison. Reject timestamps more than five minutes from your clock.
Retries and duplicates
Return a 2xx response after accepting a request. Deduplicate by event_id or the Idempotency-Key header; retries use the same event ID. Delivery is at least once, so duplicates are possible after an uncertain network outcome. Failed deliveries are retried for up to six processing attempts, then require support. Endpoints must use public HTTPS on port 443; redirects and private network addresses are not supported.
Per-permit alerts wait for source ingestion and classification. A filing is not an immediate homeowner inquiry. Pausing alerts does not pause subscription billing.