Skip to main content

Overview

The DOWNSTREAM_ENTITY_LICENSE_EXPIRED webhook is triggered the day after one of your agencies’ licenses passes its renewal date. Agency Compliance Status Change fires per product and state and only on an actual status flip, so a lapse in a state you carry no requirement for never reached you. This event does. Webhook type: DOWNSTREAM_ENTITY_LICENSE_EXPIRED

Triggers

One delivery per license, on the day after its nextRenewalDate. The day after is deliberate: a state treats the renewal date as the last valid day, so a license expiring today is still valid today. daysUntilExpiration is therefore -1 on a normal delivery, not 0.
Deliveries land on a daily sweep at 05:00 America/New_York, not in real time. This is a date crossing rather than a change to a record.

What does not fire this event

Licenses marked do-not-renew DO fire

If a license has been marked do-not-renew, this event still fires, which is the opposite of how Turris treats its own renewal reminders. For a carrier this is arguably the most useful case of all: the license you most want to hear about lapsing is the one someone let lapse on purpose.

There is no “expired” license status, and this payload proves it

The most confusing thing about this event: status on the payload normally reads "active" even though the license has expired. That is correct. status is copied verbatim from the NIPR PDB payload and nothing in Turris derives it from a date, so a license can sit at active with a renewal date years past. This event exists precisely because the status field cannot tell you what this tells you. Key on daysUntilExpiration being negative, or on nextRenewalDate being in the past. Never on status.

Perpetual licenses never fire

Both events are driven entirely by a range query on nextRenewalDate, so a license without one never produces a delivery. That is roughly 11% of agency licenses on the platform. Reconcile against Get Downstream Entity Licenses if you need the complete set.

Payload Example

Note status: "active" on an expired license, and daysUntilExpiration: -1. Both are what a real delivery looks like.

Payload Fields

The entity fields are best-effort, and they all depend on one lookup. downstreamEntityId, legalName, downstreamEntityAssociationId, branchName and producerCode are resolved from your association with the agency. If that lookup misses — an agency archived between our read and the delivery is the realistic case — none of them arrive. If it hits, downstreamEntityId and downstreamEntityAssociationId are always present and the rest are individually best-effort.One distinction worth reading carefully: an absent producerCode key means the lookup did not resolve, whereas producerCode: null means it resolved and no producer code is assigned.
There is deliberately no expirationDate field. nextRenewalDate is the only expiry date the platform holds.

Deduplication and volume

Each license matches the expired boundary on exactly one calendar day, so you receive one delivery per license per renewal cycle. No debouncing, no batching.
Size your receiver for the spike, not for the median. A typical sweep delivers single digits and the 95th percentile is under 50, but the busiest measured sweep for a single carrier carries about 1,850 deliveries of this event alone. Because renewal dates cluster on the last day of the month, this event’s spikes land on the 1st or 2nd. Return 2xx quickly and queue.
If the daily sweep does not run, that day’s licenses are not announced later. There is no catch-up pass. Reconcile against Get Downstream Entity Licenses if you need a guarantee.
Webhook subscriptions are per event type. Subscribing to Agency License Expired does not deliver Agency License Expiring — register a separate webhook for each.