Overview
TheAGENT_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 itsnextRenewalDate.
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.
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 onnextRenewalDate. 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 movesnextRenewalDate forward re-arms the event for the new date rather than cancelling anything already sent.