Skip to main content
Every delivery is an HTTPS POST with a JSON body and three headers: Failed deliveries are retried up to 6 times with backoff (10-second timeout per attempt). Respond with any 2xx quickly and process asynchronously. An endpoint that fails 20 consecutive deliveries is automatically disabled.

Verifying signatures

Compute the signature from the raw request body, compare in constant time, and reject deliveries with a timestamp older than five minutes. This protects you from replayed deliveries:
JavaScript
Python

profile.updated

Sent when a watcher run adds new events to a profile. The delivery carries the events themselves: events holds the new timeline entries in the exact shape profile reads return in sections.eventsTimeline — title, description, date with datePrecision and dateBasis, and the sources behind the event — so your handler has everything without a follow-up read, and a later profile read returns identical objects. newEventCount is the number of new events; changes lists the source-level deltas. runsCovered names how many completed runs the delivery folds together (runId is the newest), and updatedSections lists events_timeline when the delivery carries events.
events carries at most 10 entries and changes at most 25; the full timeline lives on profile reads and the full change set on watcher runs.
Slack incoming-webhook URLs receive a formatted Slack message (new-event count and a short change list) instead of this JSON. Use one for a notifications channel.

Other events

company.thesis.changed, company.alert, and portfolio.changed are delivered to endpoints subscribed to them and follow the same signing scheme. Their payloads are documented with the company intelligence APIs.