Skip to main content

Overview

The AGENT_LICENSE_EXPIRING webhook is triggered when one of your producers’ licenses is 60 days from its renewal date. It exists because a lapsing license did not reliably reach you. Agent Compliance Status Change fires per product and state, and only when a compliance status actually flips, so a license expiring in a state you have no requirement for, or one covered by another license the producer holds, is silent. Nothing announced the approaching date itself. Webhook type: AGENT_LICENSE_EXPIRING

Triggers

One delivery per license, on the day it is exactly 60 days from its nextRenewalDate.
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, so there is nothing to react to the moment it happens.
The 60 days here is not the 30 days in the Turris web app. The app’s own “Expiring Soon” badge appears at 30 days, so between 60 and 30 days out you will hold a license this webhook called expiring that the screen does not.Both numbers are correct for their purpose and neither is changing. That is why every delivery carries daysUntilExpiration and expiringWindowDays: read them rather than inferring a threshold, and the two surfaces reconcile.

What does not fire this event

Licenses the producer chose not to renew DO fire

If a producer has marked a license do-not-renew, this event still fires. That is deliberate and probably the opposite of what you would guess: Turris suppresses its own renewal reminders in that case, because there is no point nagging someone about a license they decided to drop. For a carrier the reasoning inverts. A producer deliberately letting a license lapse is one of the most actionable things you can hear, so you get told.

Perpetual licenses never fire, and there are more than you might think

Both events are driven entirely by a range query on nextRenewalDate. A license without one cannot match, so it never produces a delivery. That is roughly 9% of producer licenses on the platform. If you reconcile deliveries against your own license count you will find a gap, and this is it, not dropped events. Read Get Agent Licenses for the full picture.

There is no “expired” license status to key on

Worth stating plainly, because it looks like a bug in the payload: status is copied verbatim from NIPR and nothing in Turris derives it from a date. So a license 60 days from expiry, and one that lapsed last week, both normally carry status: "active". Use daysUntilExpiration and nextRenewalDate. Do not use status to infer expiry.

Payload Example

Payload Fields

The entity fields are best-effort, and they all depend on one lookup. agentId, downstreamEntityAssociationId, branchName and legalName are resolved from your association with the producer’s 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, downstreamEntityAssociationId is always present and the rest are individually best-effort.Absent means “we could not resolve this”, never a statement about the data. Re-read from the API rather than inferring anything from an absent field.One caveat. When a producer works under more than one of your agencies, the agency fields name an arbitrary one of those relationships, because a single NIPR subscription is shared across them. agentId is exact; treat downstreamEntityAssociationId as one of possibly several. Match on agentId.
There is deliberately no expirationDate field. nextRenewalDate is the only expiry date the platform holds. (The license GET reference currently documents an expirationDate; that field does not exist on any record and no response has ever carried a value for it.)

Deduplication and volume

Each license matches the 60-day boundary on exactly one calendar day, so you receive exactly one delivery per license per renewal cycle. There is no debouncing and no batching. A renewal that moves nextRenewalDate forward re-arms the event for the new date rather than cancelling anything already sent.
Size your receiver for the spike, not for the median. The two are three orders of magnitude apart. A typical sweep delivers single digits, and the 95th percentile is still under 50 — but the busiest measured sweep for a single carrier carries about 2,800 deliveries of this event alone.Return 2xx quickly and queue the work rather than processing inline. A receiver that handles the median sweep comfortably can still fall over on a peak one.
If the daily sweep does not run, that day’s licenses are not announced later. There is no catch-up pass. If you need a guarantee rather than a notification, reconcile against Get Agent Licenses on a schedule and treat this webhook as the fast path.
Webhook subscriptions are per event type. Subscribing to Agent License Expiring does not deliver Agent License Expired — register a separate webhook for each.