Webhooks
Subscribe a URL to the event types you want, and Truvo sends it a signed POST each time one of them happens. The event feed keeps every event for 30 days, so you can recover a delivery you missed.
Subscribe
Create a subscription with the URL that receives events and the exact event types you want. There’s no wildcard, so list each type:
Each example on this page makes a new Idempotency-Key with uuidgen. To retry an operation, send the key that it first used. See Retry safely with request keys.
The answer is the subscription, with its signing secret:
Store the signing_secret right away. It’s shown once, and a retry of a create that succeeded returns the subscription with signing_secret: null. If you lose the secret, rotate it.
If a create answers 503, send it again with the same request key, and it finishes with the same secret. A create left unfinished for 10 minutes is dropped. A retry of its request key then gets 409 with the retry action use_new_request_key, so send the create again with a new key.
A few rules apply to every subscription:
- Manage subscriptions with an API key from the portal’s Keys page. Any other key gets
403wrong_key_kind. - The URL must use
httpsand name a public host. A URL with a user name or a password, an IP address, a name with no dot such aslocalhost, or a.local,.localhost,.internal,.localdomainor.home.arpahost gets422. A port is fine. - An unknown event type gets
422at that entry ofevent_types. - Each integration can hold 10 active subscriptions in each environment.
- A sandbox key sees sandbox events, and a live key sees live events.
To change the URL or the event types, send PATCH /v1/event-subscriptions/{id}. To stop deliveries, send DELETE /v1/event-subscriptions/{id}, which disables the subscription. GET /v1/event-subscriptions lists your subscriptions, 10 to a page by default.
Rotate the signing secret
To rotate (roll) the secret, send POST /v1/event-subscriptions/{id}/rotate with a new request key. The answer carries the new secret once, and previous_secret_expires_at says when the old secret stops working: 24 hours after the rotation. Until then, each delivery carries a signature made with each secret, so your endpoint accepts it with either one. Deploy the new secret before the old one expires. Only one rotation of a subscription can be in progress, so a second one gets 409 until the first finishes. A rotation left unfinished blocks new ones for up to 10 minutes.
Verify each delivery
Anyone can send a request to your URL, so check the signature before you act on a delivery. Each delivery carries these signature headers:
The signature is an HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{body}. Its key is the part of your signing secret after whsec_, decoded from base64. Each entry in webhook-signature is v1, followed by a signature in base64.
The signature follows the Standard Webhooks scheme, so any Standard Webhooks library can verify it. This example uses the standardwebhooks package on npm:
verify throws when no signature matches, or when the timestamp is more than 5 minutes away from your clock. Answer 400 in that case and do nothing else. Verify against the raw body, because a body that you parsed and serialized again won’t match.
Handle retries and duplicates
Answer with a 2xx status within 15 seconds to confirm a delivery. Any other answer, a redirect included, counts as a failure. The first delivery goes out right away, and after a failure, Truvo sends the message again after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours, and 10 hours.
If every delivery to your URL fails for 5 days, delivery to that subscription turns off. The subscription still reads active, and its health reads disabled. To turn delivery back on, send PATCH /v1/event-subscriptions/{id} with your URL, then recover the missed events from the feed.
The same event can arrive more than once, and events can arrive out of order. Handle both:
- Store the
idof each event you processed, and skip anidyou’ve already seen. - Answer
2xxfirst, and do the work afterward. A slow handler turns into retries. - Compare
resource.versionwith the version you hold. Read the resource only when the event’s version is higher, and never apply an older version over a newer one.
Read the resource
An event says which resource changed and which version it reached. It carries no applicant data:
To see what changed, read the resource. A quote_request event points to GET /v1/quote-requests/{id}, and a quote event points to GET /v1/quotes/{id}. The read gives you the current state, which may already be newer than the event.
Events have no revision, and their fields are the same in every revision. Your read of the resource sends your Truvo-Version, and its answer follows that revision. See Versions and changes.
Truvo can add event types and fields without notice. Ignore a type or a field that you don’t know, and still answer 2xx.
Event types
Pet sends the same quote_request and quote events as auto and renters.
Recover missed events
The event feed holds every event of the last 30 days, of every type, whether or not you subscribed to it. Each event has the same id in the feed as in a webhook, so you can use one handler for both. Read the feed after an outage, after you turn a subscription back on, or on a schedule as a safety net:
The answer has events, has_more, and a next_cursor. Every page has a next_cursor, an empty one included. Process the events and store the next_cursor only after that work is saved. While has_more is true, send next_cursor as cursor to read the next page. When has_more is false, you’ve caught up; keep next_cursor and read again later.
- Leave out
cursorto start at the oldest event the feed still holds. limitis 10 by default and 100 at most.- A cursor that the feed didn’t give you gets
400with the codeinvalid_cursor. - A cursor gets
410with the codeevent_cursor_expiredwhen events after it are gone, because the feed deleted them after 30 days. Read each resource that you track, then read the feed again without a cursor.
Test your endpoint
Send a test event to check that your endpoint gets deliveries and verifies their signatures:
The answer is 202, with the event that Truvo queued:
A test event goes only to that subscription, whatever event types it lists. It names no resource and carries no applicant data, and it isn’t in the event feed. Answer it with 2xx. To retry after an error, send the same request key, and Truvo queues the same event, with the same id.
A test can take up to 35 seconds to answer, so set your client’s timeout to 40 seconds or more. If it answers 503, wait for the Retry-After seconds and send it again with the same request key.
A test to a disabled subscription gets 409. So does a test while delivery to the subscription is off: check its health.
See each delivery
GET /v1/event-subscriptions/{id}/deliveries lists the deliveries to a subscription in the last 30 days, newest first, test events included:
created_at is when Truvo sent the event to delivery. A new delivery can take some seconds to show in the log. limit is 10 by default and 100 at most. Send the next_cursor of a page as cursor to read the next page. A page can come back empty with a next_cursor, so keep reading until next_cursor is null. A cursor that this subscription’s log didn’t give you gets 400 with the code invalid_cursor.
To see the attempts of one delivery, read GET /v1/event-subscriptions/{id}/deliveries/{event_id}. The answer is the same delivery, with up to 20 attempts, newest first:
Each entry in attempts has attempted_at, status, response_status_code, response_duration_ms and trigger. response_status_code is null when your endpoint gave no HTTP answer, as after a timeout. trigger is manual for a test or a replay, and scheduled for the first attempt and each retry.
Replay a delivery
After you fix your endpoint, send an event from the delivery log again:
The answer is 202. The event arrives again with the same id and the same body, so your duplicate check still applies. You can replay only an event in the subscription’s delivery log. Any other event ID gets 404. Use a new request key for each replay, and the same key to retry after an error. To catch up on many events, read the event feed.
Check delivery health
GET /v1/event-subscriptions/{id}/health says whether deliveries get through:
Limits for the webhook tools
- A subscription takes 10 test events a minute, and each event can be replayed 5 times a day. Only a test or a replay that Truvo hands to delivery counts.
- An integration can send 60 tests and replays a minute in all.
- Tests and replays don’t use your quote request allowance.
- The delivery log, delivery, and health reads use the quote read allowance: one unit for a page of the delivery log, and up to two for a health read or a read of one delivery. The checks before a test use one unit, and the checks before a replay use two.
- A
429and a503carryRetry-After. Send the same request again after that many seconds.
An agent can use the same tools over MCP: send_test_event, list_event_deliveries, get_event_delivery, replay_event_delivery, and get_event_subscription_health.
Try it in the sandbox
Send a test event first. Then make a real change with your sandbox key, such as a new quote request. Each change sends its events to your subscriptions and adds them to the feed.