---
title: "parcel.permit_filed — a permit was filed (or first observed) for a tracked parcel"
method: POST
path: "parcel.permit_filed"
---

# parcel.permit_filed — a permit was filed (or first observed) for a tracked parcel

`POST parcel.permit_filed` (webhook)

PropRaven POSTs this event when a new permit is matched to a parcel matching one of your webhook filters. Fires once per permit per parcel; duplicate filings from the same jurisdiction de-dupe via `permit_id`. Signature verification: HMAC-SHA256 over `<unix_ms>.<raw_body>`, secret from webhook creation, header `X-PropRaven-Signature: t=<unix_ms>,v1=<sig>`. Reject if the request timestamp is more than 5 minutes from now.

## Headers

- `X-PropRaven-Signature` string, required
- `X-PropRaven-Event-Id` string, required
- `X-PropRaven-Event-Type` string, required
- `X-PropRaven-Delivery-Id` string, required
- `X-PropRaven-Attempt` string, required

## Payload

- ParcelPermitFiledEvent
  - `event_type` 'parcel.permit_filed', required
  - `event_id` string, required: Deterministic (sha256 of source, record id and event type). A retry re-sends the same event_id: de-duplicate on it.
  - `occurred_at` string, date-time, required: The record's own date when it has one, else the time PropRaven ingested it; see occurred_at_basis.
  - `occurred_at_basis` 'filed_date' | 'issued_date' | 'curated_at', required: Which column dated the event.
  - `delivery_attempt` integer, required: Starts at 1; increments on every retry (equals the X-PropRaven-Attempt header).
  - `parcel_id` string, required: The county assessor's parcel number the record was matched to (e.g. `12104406`). County-scoped, NOT unique nationally and not `county:parcel`: identify the parcel with state_fips + county_fips + parcel_id, or with canonical_id.
  - `state_fips` string, nullable, required: 2-digit state FIPS of the record; null when the publisher gave none.
  - `county_fips` string, nullable, required: 3-digit county FIPS of the record as published (a 5-digit value is cut to its last 3); null when absent. Placeholders such as `000` are passed through, not repaired.
  - `canonical_id` string: Parcel-scoped endpoints only: the watched parcel this event matched, `state_fips:county_fips:parcel_id`. Absent on state/county endpoints.
  - `match_basis` 'state_county_parcel_id' | 'state_unique_parcel_id' | 'null', nullable: Parcel-scoped endpoints only (with canonical_id): `state_county_parcel_id` = the record's own county matched; `state_unique_parcel_id` = the record's county was unknown and the parcel number is unique in the state.
  - `permit_id` string, required: PropRaven internal permit id (stable across re-ingests).
  - `permit_number` string, nullable: Jurisdiction-issued permit number.
  - `permit_type` string, nullable: Building, electrical, roofing, demolition, etc.
  - `permit_status` string, nullable: Filed, issued, in_review, final, expired, withdrawn.
  - `filed_date` string, date, nullable
  - `issued_date` string, date, nullable
  - `description` string, nullable
  - `estimated_cost` number, nullable: Declared job cost in USD.
  - `contractor_name` string, nullable
  - `contractor_license` string, nullable
  - `applicant_name` string, nullable
  - `jurisdiction_id` string, nullable: PropRaven jurisdiction id; join to /v1/jurisdictions.
  - `source_run_id` string, nullable: Reserved for the PropRaven ingest run; null today.

## Acknowledgement `2XX`

Any 2xx status acks the delivery; the body is not read. A non-2xx response is retried up to 8 attempts in all (waits of 1 min, 5 min, 15 min, 30 min, 1 h, 2 h and 6 h), then the delivery is dead_lettered. A send whose outcome is unknown (network error or timeout) stays in_flight and is not retried automatically.

---

[API](https://skmtc.dev/propraven/apis/propraven-api.md) · [All operations](https://skmtc.dev/propraven/apis/propraven-api/llms.txt) · [OpenAPI document](https://skmtc.dev/propraven/apis/propraven-api/revisions/37f8158c4eda?raw)
